T-SQL 程序,标量变量错误,即使在成功更新后
T-SQL Procedure, scalar variable error even after successful updation
--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)
我使用了 EXEC
和 sp_executesql
过程来执行我的动态查询,但都失败了。
在 EXEC
的情况下,动态查询未设置为 @SQLQUERY
变量(调试后看到),在 sp_executesql
的情况下,尽管更新了数据库,但我得到标量变量错误我已经把所有东西都传给它了。
案例很简单。您不能在 UPDATE
语句中参数化 table/column 名称:
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;
备注:
- Table 名称应具有
SYSNAME
数据类型。
- 用
QUOTENAME
引用标识符是一个好习惯(以避免潜在的 SQL 注入攻击)。
- 我猜
@CreatedBy
是 datetime
这就是为什么我不明白为什么它被传递为 varchar(256)
。
- 每条语句以
;
结尾是个好习惯。在未来的版本中,这将是强制性的。
--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)
我使用了 EXEC
和 sp_executesql
过程来执行我的动态查询,但都失败了。
在 EXEC
的情况下,动态查询未设置为 @SQLQUERY
变量(调试后看到),在 sp_executesql
的情况下,尽管更新了数据库,但我得到标量变量错误我已经把所有东西都传给它了。
案例很简单。您不能在 UPDATE
语句中参数化 table/column 名称:
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;
备注:
- Table 名称应具有
SYSNAME
数据类型。 - 用
QUOTENAME
引用标识符是一个好习惯(以避免潜在的 SQL 注入攻击)。 - 我猜
@CreatedBy
是datetime
这就是为什么我不明白为什么它被传递为varchar(256)
。 - 每条语句以
;
结尾是个好习惯。在未来的版本中,这将是强制性的。