Tsql 无法在DATEADD(@pinterval、@pinterval、@DayPlus)中使用变量

Tsql 无法在DATEADD(@pinterval、@pinterval、@DayPlus)中使用变量,tsql,variables,dynamic,sql-server-2012,Tsql,Variables,Dynamic,Sql Server 2012,我们是否有其他办法来完成这项任务?我必须在循环中完成它,所以我不能每次都根据间隔值定义它。仅日期部分不能作为变量接受,因为如果我使用 DECLARE @pinterval INT = 1, @DayPlus DATETIME = '2016-07-01', @datepart VARCHAR(20) = 'MONTH' SET @DayPlus = DATEADD(@datepart, @pinterval, @DayPlus) SELECT @DayPlus 那么它工作得很好。不确定,但我能

我们是否有其他办法来完成这项任务?我必须在循环中完成它,所以我不能每次都根据间隔值定义它。仅日期部分不能作为变量接受,因为如果我使用

DECLARE @pinterval INT = 1, @DayPlus DATETIME = '2016-07-01', @datepart VARCHAR(20) = 'MONTH'
SET @DayPlus = DATEADD(@datepart, @pinterval, @DayPlus)
SELECT @DayPlus

那么它工作得很好。不确定,但我能理解这个问题,但我正在寻求快速解决方案。我访问过web,但没有得到确切的解决方案。

不可能将第一个参数替换为1,因为这里需要的是名称,而不是字符串

您最多只能使用一个
CASE
表达式:

DATEADD(MONTH, @pinterval, @DayPlus) 

1文件中甚至规定了这一点:

用户定义的变量等效项无效


不可能用变量替换1的第一个参数,因为这里需要的是名称,而不是字符串

您最多只能使用一个
CASE
表达式:

DATEADD(MONTH, @pinterval, @DayPlus) 

1文件中甚至规定了这一点:

用户定义的变量等效项无效


您可以使用动态SQL:

SET @DayPlus =
CASE @datepart
    WHEN 'MONTH' THEN DATEADD(MONTH, @pinterval, @DayPlus)
    WHEN 'YEAR' THEN DATEADD(YEAR, @pinterval, @DayPlus)
    WHEN 'DAY' THEN DATEADD(DAY, @pinterval, @DayPlus)
    --TODO - add all parts you might wish to use
END
使用此选项有两个原因:

  • 为了最小化SQL注入风险,它不会因为@datepart而消除它
  • 它将确保动态查询的计划被缓存,这对于简单查询可能是有益的(查询时间和编译时间很重要)

  • 您可以使用动态SQL:

    SET @DayPlus =
    CASE @datepart
        WHEN 'MONTH' THEN DATEADD(MONTH, @pinterval, @DayPlus)
        WHEN 'YEAR' THEN DATEADD(YEAR, @pinterval, @DayPlus)
        WHEN 'DAY' THEN DATEADD(DAY, @pinterval, @DayPlus)
        --TODO - add all parts you might wish to use
    END
    
    使用此选项有两个原因:

  • 为了最小化SQL注入风险,它不会因为@datepart而消除它
  • 它将确保动态查询的计划被缓存,这对于简单查询可能是有益的(查询时间和编译时间很重要)
  • 如果这是唯一的方法,那么我必须重复10多次

    否,使用
    交叉应用


    @听起来不错,你能帮我把完整的代码作为答案吗。求你了

    关于
    交叉应用
    :动态生成类似变量的内容

    DECLARE @pinterval INT = 1, 
      @DayPlus DATETIME = '2016-07-01', 
      @datepart NVARCHAR(20) = 'MONTH'
    
    DECLARE @sql NVARCHAR(MAX) = N'SET @DayPlus = DATEADD('+@datepart+', @pinterval, @DayPlus)',
           @params NVARCHAR(MAX) = N'@DayPlus DATETIME OUTPUT, @pinterval INT'
    
    EXEC sp_executesql @sql, @params, @pinterval = @pinterval, @DayPlus = @DayPlus OUTPUT
    
    SELECT @DayPlus
    
    如果这是唯一的方法,那么我必须重复10多次

    否,使用
    交叉应用


    @听起来不错,你能帮我把完整的代码作为答案吗。求你了

    关于
    交叉应用
    :动态生成类似变量的内容

    DECLARE @pinterval INT = 1, 
      @DayPlus DATETIME = '2016-07-01', 
      @datepart NVARCHAR(20) = 'MONTH'
    
    DECLARE @sql NVARCHAR(MAX) = N'SET @DayPlus = DATEADD('+@datepart+', @pinterval, @DayPlus)',
           @params NVARCHAR(MAX) = N'@DayPlus DATETIME OUTPUT, @pinterval INT'
    
    EXEC sp_executesql @sql, @params, @pinterval = @pinterval, @DayPlus = @DayPlus OUTPUT
    
    SELECT @DayPlus
    


    是的,
    DATEADD
    的第一个参数需要是日期组件的名称。不是包含日期组件名称的字符串(文字或变量)。这意味着无论如何都不可能。是的,它是。。。如果使用动态查询,则
    DATEADD
    的第一个参数必须是日期组件的名称。不是包含日期组件名称的字符串(文字或变量)。这意味着无论如何都不可能。是的,它是。。。如果您真的想返回结果,请使用动态查询
    @DayPlus=@DayPlus OUTPUT
    。@Damien\u不信者谢谢!错过了。
    @DayPlus=@DayPlus OUTPUT
    如果你真的想拿回结果。@Damien\u不信者谢谢!错过了。谢谢你的回复,如果这只是一种方式,那么我必须重复超过10次,如果我与那么多的日期部分工作???@Suraz可能没有。。。阅读关于交叉应用(选择…)作为t。这允许您放置计算一次,并将其结果用作命名的派生结果column@Shnugo听起来不错,你能帮我把完整的代码作为答案吗。请谢谢你的回复,如果这只是一种方式,那么我必须重复这超过10次,如果我与那么多的日期部分工作???@Suraz可能没有。。。阅读关于交叉应用(选择…)作为t。这允许您放置计算一次,并将其结果用作命名的派生结果column@Shnugo听起来不错,你能帮我把完整的代码作为答案吗。请感谢先生+1的努力和独特的解决方案。感谢先生+1的努力和独特的解决方案。