替换动态查询中的列名

Substitute Column name in dynamic queries

我有一个过程,其中我接收参数列名并通过替换列名创建动态查询。

当我直接运行这个动态查询时它工作正常。

declare @a datetime,
@b varchar(50) ='CREATED_DATE',--column name
@query varchar(500);
select  @a= CONVERT(datetime,LAST_RUN_PROC,121) from TEST_TABLE_MASTER


exec( 'select '+@b+' from TEST1 where '+@b+' = '+''''+@a+'''' )

但是当我将查询存储在一个变量中然后执行时,它显示错误。 下面的代码显示错误

declare @a datetime,
@b varchar(50) ='CREATED_DATE',--column name
@query varchar(500);
select  @a= CONVERT(datetime,LAST_RUN_PROC,121) from TEST_TABLE_MASTER

SET @query=  'select '+@b+' from TEST1 where '+@b+' = '+''''+@a+'''' --this line showing error Conversion failed when converting date and/or time from character string.

exec (@query)

我卡住了here.please求助

  1. 连接 SQL 字符串不是最好的主意,因为需要多个 ''''。它容易出错且难以调试。

  2. 使用正确的类型(table名称,列名)-SYSNAME,查询-NVARCHAR(MAX).

  3. 您可以使用 REPLACE 占位符来填充值或将它们作为参数传递给 EXEC dbo.sp_executesql

  4. 总是引用 table/column 个名字。

  5. SELECT @a= CONVERT(datetime, LAST_RUN_PROC,121) FROM TEST_TABLE_MASTER; 将设置 @a 最后从 table 读取的值,您应该添加 TOP 1ORDER BY.

代码:

DECLARE @a DATETIME,
        @b SYSNAME            ='CREATED_DATE',
        @query NVARCHAR(MAX);

SELECT  @a= CONVERT(datetime, LAST_RUN_PROC,121) FROM TEST_TABLE_MASTER;

SET @query = 
   N'SELECT <col_name>
     FROM TEST1
     WHERE <col_name> = ''<col_value>'';';

SET @query = REPLACE(@query, '<col_name>', QUOTENAME(@b));     
SET @query = REPLACE(@query, '<col_value>', @a);  

--SELECT @query;

EXEC [dbo].[sp_executesql]
     @query;

SqlFiddleDemo

带有参数传递和 dbo.sp_executesql 而不是 EXEC 的推荐版本:

DECLARE @a DATETIME,
        @b SYSNAME            ='CREATED_DATE',
        @query NVARCHAR(MAX);

SELECT @a= LAST_RUN_PROC FROM TEST_TABLE_MASTER;

SET @query = 
   N'SELECT <col_name>
     FROM TEST1
     WHERE <col_name> = @a;';

SET @query = REPLACE(@query, '<col_name>', QUOTENAME(@b));     

EXEC [dbo].[sp_executesql]
     @query
     ,N'@a DATETIME'
     ,@a;

SqlFiddleDemo2

警告:

使用 Dynamic-SQL 责任重大。看不懂就别用Dynamic-SQL.

编辑:

我已经设法 运行 你的例子,但我强烈建议使用上面的解决方案之一:

SET @query=  'select '+@b+' from TEST1 where '+@b+' = '+''''+CONVERT(varchar(19),@a, 121)+'''' 

SqlFiddleDemo3