Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server “动态SQL”;“声明标量变量”;错误_Sql Server_Stored Procedures_Dynamic Sql - Fatal编程技术网

Sql server “动态SQL”;“声明标量变量”;错误

Sql server “动态SQL”;“声明标量变量”;错误,sql-server,stored-procedures,dynamic-sql,Sql Server,Stored Procedures,Dynamic Sql,我创建了以下过程,每次尝试执行时都会出现错误 必须声明标量变量@BatchId 基本上,我所要做的就是将原始表的内容插入到主表中,主表中的所有插入行都有一个批次id(由sequencer创建)。这看起来很简单,但不能正常工作 CREATE PROCEDURE [dbo].[usp_SessionsAppend] @RawTable NVARCHAR(500) AS DECLARE @BatchId BIGINT, @SQLString NVARCHAR(MAX) SE

我创建了以下过程,每次尝试执行时都会出现错误

必须声明标量变量@BatchId

基本上,我所要做的就是将原始表的内容插入到主表中,主表中的所有插入行都有一个批次id(由sequencer创建)。这看起来很简单,但不能正常工作

CREATE PROCEDURE [dbo].[usp_SessionsAppend]
    @RawTable NVARCHAR(500)
AS 
    DECLARE @BatchId BIGINT, @SQLString NVARCHAR(MAX)

    SET @BatchId = NEXT VALUE FOR [dbo].[BatchID]

    SET @SQLString = 
        'INSERT INTO [Master].[Sessions] (
         [ImportTimestamp]
        ,[TransactionId]
        ,[ParticpantId]
        ,[ProviderId]
        ,[ActivityDate]
        ,[Attended]
        ,[Minutes]
        ,[SurveyCompleted]
        ,[Instructor]
        ,[InstructorID]
        ,[ProgramCode]
        ,[BatchId]
        )

        SELECT
         GETDATE() AS [ImportTimeStamp]
        ,NEWID() AS [TransactionId]
        ,[ParticpantId]
        ,[ProviderId]
        ,[ActivityDate]
        ,[Attended]
        ,[Minutes]
        ,[SurveyCompleted]
        ,[Instructor]
        ,[InstructorID]
        ,[ProgramCode]
        ,@BatchId
        FROM' + @RawTable

    EXECUTE (@SQLString)
任何帮助或见解都将不胜感激。

用于将参数传递到动态SQL

乙二醇


此错误的原因是变量@BatchId超出了动态sql的范围。但这只是问题的一部分。在这里,您也容易受到sql注入的攻击。为什么必须传入表名?这表明设计不够理想。你也需要在“FROM”后面加一个空格。但这仍然容易受到sql注入的影响,但这更像是一个设计问题,在传递表名时无法解决。
 declare @BatchId int = NEXT VALUE FOR [dbo].[BatchID]

 declare @RawTable nvarchar(200) = 'foo';

 declare @SQLString nvarchar(max) = 
        'INSERT INTO [Master].[Sessions] (
         [ImportTimestamp]
        ,[TransactionId]
        ,[ParticpantId]
        ,[ProviderId]
        ,[ActivityDate]
        ,[Attended]
        ,[Minutes]
        ,[SurveyCompleted]
        ,[Instructor]
        ,[InstructorID]
        ,[ProgramCode]
        ,[BatchId]
        )

        SELECT
         GETDATE() AS [ImportTimeStamp]
        ,NEWID() AS [TransactionId]
        ,[ParticpantId]
        ,[ProviderId]
        ,[ActivityDate]
        ,[Attended]
        ,[Minutes]
        ,[SurveyCompleted]
        ,[Instructor]
        ,[InstructorID]
        ,[ProgramCode]
        ,@BatchId
        FROM ' + quotename(@RawTable)

    print @SQLString
    exec sp_executesql @SQLString, N'@BatchId int', @BatchId = @BatchId;