我收到了错误
为dateadd指定的参数1无效。
当我尝试在SQL Server 2012中执行以下动态参数化查询时:
DECLARE @Interval nvarchar(5) = 'DAY'
DECLARE @Increment int = 10
DECLARE @BaseDate date = getdate()
DECLARE @ResultDate date
DECLARE @Query nvarchar(2000)
SET @Query = 'SELECT @result = DATEADD(@Interval, @Increment, CAST(@BaseDate AS DATE))'
EXECUTE sp_executesql @Query,
N'@result date OUTPUT, @Interval varchar(50), @Increment int, @BaseDate date',
@Interval = @Interval, @Increment = @Increment,
@BaseDate = @BaseDate, @result = @ResultDate OUTPUT
SELECT @ResultDate
我已将SET @Query
行更改为此行。
SET @Query = 'SELECT @result = DATEADD(' + @Interval +', @Increment, CAST(@BaseDate AS DATE))'
虽然它工作正常,但我很好奇为什么第一个语句在我的动态SQL查询中导致错误? sp_executesql
不生成与连接查询相同的语句吗?
答案 0 :(得分:2)
因此,考虑参数化动态sql的方法是,如果它是静态SQL,则只能使用参数。 DATEADD
需要特殊的日期部分关键字(例如day, hour, year
等),而不是文字字符串,而不是变量。一些人遇到的问题与他们认为可以参数化类似表名的东西相同。第一个语句失败,因为即使在静态sql中,这也是无效的:
declare @increment nvarchar(5) = 'day'
select dateadd(@increment, 1, getdate())
相当于
select dateadd('day', 1, getdate())
第二个陈述成功,因为你要连接字符串" day"它被评估为关键字。
答案 1 :(得分:2)
在第一种情况下,查询(@Interval
扩展到其值)变为:
SELECT @result=DATEADD('DAY', @Increment, CAST(@BaseDate AS DATE))
在第二个查询中它变为:
SELECT @result=DATEADD(DAY, @Increment, CAST(@BaseDate AS DATE))
第一个查询无效,因为DATEADD的第一个参数是字符串值,编译器需要语言关键字,而SQL中的那些不一样
有关详细信息,请参阅此处:https://docs.microsoft.com/en-us/sql/t-sql/functions/dateadd-transact-sql
请注意 datepart 下的行User-defined variable equivalents are not valid
。换句话说,你不能在这些"值"周围加上引号,它们不是字符串而是关键字,它们不能放在变量中。