【问题标题】:T-SQL Procedure, scalar variable error even after successful updationT-SQL过程,即使成功更新后标量变量错误
【发布时间】:2016-08-08 05:39:18
【问题描述】:
--sp_executesql version
    --SET @SQLQUERY = 'UPDATE @TableName SET Brief = @Brief,
    --               [Full] = @Full,                        
    --               CreatedBy = @CreatedBy,
    --               Department = @Department,
    --               Answer = @Answer WHERE Id=@Id';
 --SET @ParamDefinition=N'@TableName nvarchar(50),@Brief nvarchar(50),@Full nvarchar(MAX),@CreatedBy varchar(256),@Department varchar(256),@Answer nvarchar(MAX),@Id int' 
--  exec sp_executesql @SQLQUERY,@ParamDefinition,@TableName,@Brief,@Full,@CreatedBy,@Department,@Answer,@Id; 

-- exec version
SET @SQLQUERY = 'UPDATE ' + @TableName + ' SET  
                     Brief ='+ @Brief+',
                     [Full] ='+ @Full+',                        
                     CreatedBy ='+ @CreatedBy+',
                     Department ='+ @Department+',
                     Answer ='+@Answer+' WHERE Id='+CAST(@Id as nvarchar(10))

print @SQLQUERY; 
EXEC (@SQLQUERY)

我同时使用了EXECsp_executesql 程序来执行我的动态查询,但都失败了。

EXEC 的情况下,动态查询未设置为@SQLQUERY 变量(在调试后看到),在sp_executesql 的情况下,虽然数据库已更新并且我已经将所有内容传递给它,但我得到标量变量错误.

【问题讨论】:

    标签: sql sql-server tsql stored-procedures dynamic-sql


    【解决方案1】:

    案例很简单。您不能在UPDATE 语句中参数化表/列名称:

    SET @SQLQUERY = 'UPDATE @TableName       --here is problem
                     SET    Brief = @Brief, 
                            [Full] = @Full,                        
                            CreatedBy = @CreatedBy,
                            Department = @Department,
                            Answer = @Answer 
                     WHERE Id=@Id';
    
    
    SET @ParamDefinition=N'@TableName nvarchar(50),@Brief nvarchar(50), 
                           @Full nvarchar(MAX), @CreatedBy varchar(256),
                           @Department varchar(256),@Answer nvarchar(MAX),@Id int' 
    
    EXEC dbo.sp_executesql @SQLQUERY,@ParamDefinition,
                            @TableName,@Brief,@Full,
                            @CreatedBy,@Department,@Answer,@Id;
    

    改用替换:

    SET @SQLQUERY = N'UPDATE <tab_name> 
                      SET Brief     = @Brief, 
                         [Full]     = @Full,                        
                         CreatedBy  = @CreatedBy,
                         Department = @Department,
                         Answer     = @Answer 
                      WHERE Id = @Id';
    
    SET @SQLQUERY = REPLACE(@SQLQUERY, '<tab_name>', QUOTENAME(@TableName));
    
    SET @ParamDefinition=N'@Brief nvarchar(50),@Full nvarchar(MAX),
                           @CreatedBy varchar(256),@Department varchar(256),
                           @Answer nvarchar(MAX),@Id int';
    
    EXEC [dbo].[sp_executesql] @SQLQUERY,
                               @ParamDefinition,
                               @Brief,@Full,@CreatedBy, @Department,@Answer,@Id;
    

    注意事项:

    • 表名应具有SYSNAME 数据类型。
    • 最好用QUOTENAME 引用标识符(以避免潜在的SQL 注入攻击)。
    • 我猜@CreatedBydatetime 这就是为什么我不明白为什么它被传递为varchar(256)
    • 最好以; 结束每个语句。在未来的版本中,这将是强制性的。

    【讨论】:

    • 感谢我在过去 12 小时内一直坚持下去:D
    猜你喜欢
    • 2013-01-16
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 2015-04-22
    • 1970-01-01
    相关资源
    最近更新 更多