我有一个程序,我收到一个参数列名,并通过替换列名来创建动态查询。
当我直接运行这个动态查询时,它的工作正常。
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)
我被困在这里。请帮忙
答案 0 :(得分:3)
连接SQL字符串不是最好的主意,因为需要多个''''
。它容易出错并且难以调试。
使用正确的类型(表名,列名) - SYSNAME
,查询 - NVARCHAR(MAX)
。
您可以使用REPLACE
占位符填充值或将其作为参数传递给EXEC dbo.sp_executesql
。
始终引用表/列名称。
SELECT @a= CONVERT(datetime, LAST_RUN_PROC,121) FROM TEST_TABLE_MASTER;
会在表中设置@a
上次读取的值,您应该添加TOP 1
和ORDER 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
强>