我有一个更新变量列的简单查询。此查询稍后是string.Formatted并传递给SqlCommand(c#)(TableId是SomeTable中的一列):
"UPDATE SomeTable set {0}=@Value where TableId=@TableId"
我需要将此查询转换为存储过程。它有可能吗?
答案 0 :(得分:6)
它只能通过存储过程中的动态SQL来完成(正如Brad已经回答的那样,当然你会使用QUOTENAME(@columnName)
来正确防止SQL注入,并使用sysname
参数类型)。如果你走这条路,我建议你先阅读The Curse and Blessings of Dynamic SQL。
更新:
我不得不发布代码,因为Brad的代码有太多错误。
create procedure myCustomUpdate
@columnName sysname,
@value sql_variant,
@id int
AS
declare @sql NVARCHAR(max);
set @sql = N'UPDATE SomeTable SET ' + QUOTENAME(@columnName)
+ N' = @value WHERE TableId = @id';
exec sp_executesql @sql, N'@value sql_variant, @id int', @value, @id;
答案 1 :(得分:4)
我对你正在做的事情做了一些假设,但是要评估这段代码。
CREATE PROCEDURE UpdateTableValue
(
@tableId INT
,@columnName sql_variant
,@value VARCHAR(10)
)
AS
BEGIN
DECLARE @sql NVARCHAR(MAX)
SET @sql = N'UPDATE SomeTable '
+ N'SET ' + QUOTENAME(@columnName) + N' = = @value '
+ N'WHERE TableId = @tableId'
EXEC sp_executesql @sql
, N'@value sql_variant, @tableId int'
, @value, @tableId;
END
答案 2 :(得分:1)
我认为Remus提到的文章中有一个更好的解决方案:The Curse and Blessings of Dynamic SQL 。我最终使用CASE开关来优化性能(动态SQL没有被缓存),如文章所述:
UPDATE tbl
SET col1 = CASE @colname WHEN 'col1' THEN @value ELSE col1 END,
col2 = CASE @colname WHEN 'col2' THEN @value ELSE col2 END,