首页 > 解决方案 > 动态存储过程未更新 SQL Server 表

问题描述

在过去的几天里,由于我遇到的问题,我正在拔头发。

在存储过程中,我想使用列名作为参数来更新表中的值。

我有以下代码

ALTER PROCEDURE [dbo].[Item_Update_Single]
    @Id nvarchar(15), 
    @ColumnName nvarchar(80),
    @NewValue nvarchar(80)
AS 
    DECLARE @sql NVARCHAR(MAX)

    SET @sql = N'UPDATE [Item] SET [' + QUOTENAME(@ColumnName) + ']' + '= ' + QUOTENAME(@NewValue) +' WHERE [Id] = ' + @Id

    PRINT @sql

存储过程运行良好,没有错误,但表没有更新。如果我@SQL在查询窗口中运行字符串,数据就会更新。

我是一个新手,但我在这里做错了什么?

标签: sql-servertsql

解决方案


你永远不会执行你的动态语句。你的使用QUOTENAME也是错误的。'[' + QUOTENAME(@ColumnName) + ']'将导致[[ColumnName]]并且QUOTENAME(@NewValue)将引用一个列,该列的名称为 中的任何值@NewValue,而不是字符串文字。您应该对语句进行参数化并正确注入动态对象:

ALTER PROCEDURE [dbo].[Item_Update_Single] @Id int, --Guess this is actually an int
                                           @ColumnName sysname, --Corrected data type
                                           @NewValue nvarchar(80) --I assume this is correct

AS 
BEGIN

    DECLARE @sql NVARCHAR(MAX);

    SET @sql = N'UPDATE dbo.[Item] SET ' + QUOTENAME(@ColumnName) + ' = @NewValue WHERE [Id] = @ID;'

    EXEC sys.sp_executesql @SQL, N'@NewValue nvarchar(80),@Id int', @NewValue, @ID;

END

然而,这似乎是一个XY 问题。像这样的解决方案几乎总是一个坏主意,并且经常会推断出一个重大的设计缺陷。


推荐阅读