动态查询和日期部分问题 SQL
Issue with dynamic query and datepart SQL
我遇到错误
Invalid parameter 1 specified for dateadd.
当我尝试在 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
生成的语句是否与串联查询生成的语句相同?
因此,考虑参数化动态 sql 的方法是,如果参数是静态的 SQL,您只能在可以使用的地方使用参数。 DATEADD
需要一个特殊的日期部分关键字(例如 day, hour, year
等),而不是文字字符串,也不是变量。一些人 运行 认为他们可以参数化 table 名称之类的东西也是同样的问题。第一条语句失败,因为即使在静态 sql 中,这也是无效的:
declare @increment nvarchar(5) = 'day'
select dateadd(@increment, 1, getdate())
这相当于
select dateadd('day', 1, getdate())
第二个语句成功,因为您将字符串 "day" 连接到 关键字 。
在第一种情况下,查询(@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
。换句话说,你不能在这些"values"两边加上引号,它们不是字符串而是关键字,它们不能放在变量中。
我遇到错误
Invalid parameter 1 specified for dateadd.
当我尝试在 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
生成的语句是否与串联查询生成的语句相同?
因此,考虑参数化动态 sql 的方法是,如果参数是静态的 SQL,您只能在可以使用的地方使用参数。 DATEADD
需要一个特殊的日期部分关键字(例如 day, hour, year
等),而不是文字字符串,也不是变量。一些人 运行 认为他们可以参数化 table 名称之类的东西也是同样的问题。第一条语句失败,因为即使在静态 sql 中,这也是无效的:
declare @increment nvarchar(5) = 'day'
select dateadd(@increment, 1, getdate())
这相当于
select dateadd('day', 1, getdate())
第二个语句成功,因为您将字符串 "day" 连接到 关键字 。
在第一种情况下,查询(@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
。换句话说,你不能在这些"values"两边加上引号,它们不是字符串而是关键字,它们不能放在变量中。