【问题标题】:Dynamic Column Name in SQL in Update statement更新语句中 SQL 中的动态列名
【发布时间】:2015-01-08 22:50:27
【问题描述】:
DECLARE @sql NVARCHAR(max)
DECLARE @ParmDefinition NVARCHAR(500)
SET @sql = 'UPDATE [Table1] SET [Table1].[@columnName] = TEST';
SET @ParmDefinition = N'@columnName NVARCHAR(50)';
EXEC sp_executesql @sql, @ParmDefinition, @columnName = N'MyColumn';

当我运行上述查询时,我得到Invalid column name '@columnName'.。显然,运行查询时列名没有被替换。

实际上,我的@sql 变量要大得多,而且我有很多列要更新,因此我想避免对列名的所有枚举执行SET SQL =

我想声明一次 sql 字符串,然后用不同的值调用查询。例如:

EXEC sp_executesql @sql, @ParmDefinition, @columnName = N'MyColumn';
EXEC sp_executesql @sql, @ParmDefinition, @columnName = N'AnotherColumn';
EXEC sp_executesql @sql, @ParmDefinition, @columnName = N'YetAnotherColumn';
-- And so on

这样的事情可能吗?

【问题讨论】:

    标签: sql-server sp-executesql


    【解决方案1】:

    是的,您必须在字符串之外连接变量。换句话说:

    SET @sql = 'UPDATE [Table1] SET [Table1].[' + @columnName + '] = t1.Value ' +
    

    编辑:我们使用的另一个解决方案是替换基本 sql 中的标记以构造一个新的 sql 变量以供执行。

    DECLARE @sql nvarchar(max) = 'SELECT @ColumnName FROM @TableName';
    
    DECLARE @sql2 nvarchar(max) = REPLACE(REPLACE(@sql,'@ColumnName',@ColumnNameVariable),'@TableName',@TableNameVariable)
    
    EXEC (@sql2)
    
    ...Some code that changes the values of @ColumnNameVariable and @TableNameVariable...
    
    DECLARE @sql2 nvarchar(max) = REPLACE(REPLACE(@sql,'@ColumnName',@ColumnNameVariable),'@TableName',@TableNameVariable)
    
    EXEC (@sql2)
    

    您会注意到 SQL2 的 Declaration 和 Exec 在这两种情况下是完全相同的行。如果适用,这有助于在 LOOP 中使用。 (除非你不会在循环中声明 @Sql2...只是填充/重新填充它)。

    【讨论】:

    • 我希望能够运行 sp_executesql 并使用不同的值提供 @columnName
    • 实际上,我的@sql 变量要大得多。我想声明一次 sql 字符串,然后用不同的值调用查询。
    • 好的,我明白你的意思了。您可以尝试 Xedni 的解决方案,或者我将使用我们过去使用的另一个解决方案来编辑​​我的答案。
    【解决方案2】:

    首先,感谢您尝试使用 sp_executesql 参数化您的 dsql。问题是,您只能参数化最初可以放入变量中的内容,例如搜索谓词或选择列表。

    不过还是有可能的;只需将列名与您的 DSQL 字符串连接起来,用 quotename 函数包装它

    set @sql = 'update table1 set table1.' + quotename(@ColumnName) + ' = ...
    

    【讨论】:

    • 如果我有(我有)多列,我必须为每一列SET @sql = ...,是吗?
    • 是的,有条件的。我不确切知道您要完成什么,但理论上您也可以构造一个包含您要更新的所有列的单个字符串,然后立即运行它。此外,无论是更新一行中的单个值,还是更新行中的每一列,SQL 都必须完成同样多的工作。除非在执行更新时不知道其中的列,否则您可以使用静态类型的 SQL 执行此操作,并且 isnulls update table1 set Column1 = isnull(@column1, Column1) Column2, isnull(@column2, Column2)跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 2011-04-25
    • 2013-05-28
    相关资源
    最近更新 更多