SQL - 使用变量 table 和列名执行 `CASE` 语句

SQL - Executing a `CASE` satement with variable table and column names

您好,我正在尝试 运行 将这个更新查询变成一个工具,我可以在其中定义 table 和变量中的列名。

Declare @ExecQuery as nvarchar(max)
Declare @tableName as nvarchar(50)
Declare @Colfrom  as nvarchar(50)
Declare @Colto as nvarchar(50)

Set @TableName = 'upd_employees'
Set @ColFrom = 'EmpCode_Edit'
Set @ColTo = 'EmpName'

--Set @ExecQuery = 'Select '+@Colfrom+','+@Colto+' from '+@TABLENAME

Set @ExecQuery = 'update '+@TABLENAME+' set '+@Colto+' = CASE CHARINDEX('-','+@Colfrom+')
                                     WHEN 0 THEN EmpCode_Edit 
                                     ELSE
                                       CASE CHARINDEX('-',SUBSTRING('+@Colfrom+',CHARINDEX('-','+@Colfrom+')+1,LEN('+@Colfrom+')-CHARINDEX('-','+@Colfrom+')+1))
                                         WHEN 0 THEN SUBSTRING('+@Colfrom+',1,(CHARINDEX('-','+@Colfrom+')-1))
                                         ELSE SUBSTRING('+@Colfrom+',1,
                                              CHARINDEX('-','+@Colfrom+')+
                                              CHARINDEX('-',SUBSTRING('+@Colfrom+',CHARINDEX('-','+@Colfrom+')+1,LEN('+@Colfrom+')-CHARINDEX('-','+@Colfrom+')+1))-1)
                                       END
                                   END'

EXEC sp_executesql @ExecQuery

当我 运行 查询时,我得到这个错误:

Msg 402, Level 16, State 1, Line 12 The data types nvarchar and varchar are incompatible in the subtract operator.

我知道你不能直接将 table 和列名保存为变量但是当我使用相同的方法 Set @ExecQuery 作为字符串然后 运行 使用 EXEC sp_executesql @ExecQuery 它适用于简单的查询(见评论 --Set @ExecQuery = 'Select '+@Colfrom+','+@Colto+' from '+@TABLENAME)。为什么我在这个 CASE 语句中使用它时它不起作用?

查看这一行:

Set @ExecQuery = 'update '+@TABLENAME+' set '+@Colto+' = CASE CHARINDEX('-','+@Colfrom+')

您在串联语句之间有一个文字 -,而不是在您的 VARCHAR 中。如果要构建包含单引号的 Dynamic SQL,则需要双单引号。

应该变成:

Set @ExecQuery = 'update '+@TABLENAME+' set '+@Colto+' = CASE CHARINDEX(''-'','+@Colfrom+')

将这种工作方式应用于您的其余查询。


备注:

  1. 通常您最好使用 QUOTENAME 引用 table 名称和列名称。即允许 table 名称和列名称带有空格和其他特殊字符。
Set @ExecQuery = 'update '+QUOTENAME(@TABLENAME)+' set '+QUOTENAME(@Colto)+' = CASE CHARINDEX(''-'','+QUOTENAME(@Colfrom)+')
  1. 如果您以这种方式在动态 SQL 语句中连接字符串,您可能会让自己受到 SQL 注入攻击。您最好在附加的字符串中用两个单引号替换单引号:
SET @TABLENAME=REPLACE(@TABLENAME,'''','''''');
SET @Colto=REPLACE(@Colto,'''','''''');