【问题标题】:How do I execute an If statement inside a CTE如何在 CTE 中执行 If 语句
【发布时间】:2019-01-23 18:13:37
【问题描述】:

我需要根据 SSRS 报告参数的值创建一个 cte。附加代码中的 If 语句在 cte 外执行得很好,但在 cte 内执行错误。

我和我的一位同事花了几个小时试图解决这个问题,但没有成功。我尝试过使用 CASE 语句。我尝试将 WITH cteIngnoreCommID AS 放在 IF 和 ELSE 中,但没有任何效果。 此 cte 将在创建另一个 cte 的后续代码中加入。希望有人能告诉我我需要做什么。

--Declare and set Report parameter for testing purposes only
Declare @IgnoreYear as varchar(4)='2010'
;
WITH cteIgnoreCommID as (
    IF @IgnoreYear=''
        -- create cte with one record have blank values
        Select '' as IgnoreComm_ID
            ,'' as IgnoreYear
            ,0 as IngnoreBalFwd
    ELSE 
        -- create cte with records obtained from multiple tables.
        -- for proof of concept I am just creating one record.
        Select '30710000' as IgnoreComm_ID
            ,@IgnoreYear as IgnoreYear
            ,5000 as IngnoreBalFwd
                        )
--The above code run just fine if you comment out the cte lines.

如果在 cte 之外运行 IF/ELSE,我会得到正确的结果。当使用 cte 编写运行时,出现以下 2 个错误:

Msg 156, Level 15, State 1, Line 5 关键字附近的语法错误 '如果'。消息 102,级别 15,状态 1,第 13 行 ')' 附近的语法不正确。

【问题讨论】:

    标签: tsql ssrs-2012


    【解决方案1】:

    最简单的方法是在 CTE 中使用 CASE 语句。你可以修改你的 CTE 看起来像这样,它应该做你想做的事:

    Declare @IgnoreYear as varchar(4)='2010'
    ;
    WITH cteIgnoreCommID as (
            Select CASE WHEN @IgnoreYear='' THEN '' 
                    ELSE '30710000' 
                    END AS IgnoreComm_ID
                ,CASE WHEN @IgnoreYear='' THEN '' 
                    ELSE @IgnoreYear
                    END as IgnoreYear
                ,CASE WHEN @IgnoreYear='' THEN 0 
                    ELSE 5000
                    END as IngnoreBalFwd
         )
    

    【讨论】:

      【解决方案2】:

      您可以将if放在CTE之外,而是根据条件进行CTE声明:

      if 3 > 2
      
      BEGIN 
      ;WITH cte AS (
      SELECT 1 AS val
      )
      SELECT * 
      FROM cte 
      END 
      
      ELSE 
      
      BEGIN 
      ;WITH cte AS (
      SELECT 2 AS val
      )
      SELECT * 
      FROM cte 
      END
      

      使用您的代码:

      Declare @IgnoreYear as varchar(4)='2010'
      IF @IgnoreYear=''
      
      BEGIN 
      ;WITH cteIgnoreCommID AS (
      -- create cte with one record have blank values
              Select '' as IgnoreComm_ID
                  ,'' as IgnoreYear
                  ,0 as IngnoreBalFwd
      )
      SELECT * 
      FROM cteIgnoreCommID
      END
      
      ELSE 
      
      BEGIN 
      ;WITH cteIgnoreCommID AS (
      Select '30710000' as IgnoreComm_ID
                  ,@IgnoreYear as IgnoreYear
                  ,5000 as IngnoreBalFwd
      )
      
      SELECT * 
      FROM cteIgnoreCommID
      END
      

      【讨论】:

      • 在我收到的 3 个回复中,这是最接近工作的。这确实会根据 @IgnoreYear 的值创建具有不同数据的相同 CTE。但是,一旦生成了这个 CTE,我需要将它与其他 3 个 CTE 一起加入。因此,为此,我必须在 2 BEGIN / END 之间重复相同的代码,这使得修改更加困难。
      • @MickB 或者如果让结果集持久化是您必须克服的障碍,则将结果插入临时表。
      【解决方案3】:

      你可以这样做:

      Declare @IgnoreYear as varchar(4)='2010'
      ;
      WITH cteIgnoreCommID as (
              -- create cte with one record have blank values
              Select '' as IgnoreComm_ID
                  ,'' as IgnoreYear
                  ,0 as IngnoreBalFwd WHERE @IgnoreYear = ''
              UNION ALL
              -- create cte with records obtained from multiple tables.
              -- for proof of concept I am just creating one record.
              Select '30710000' as IgnoreComm_ID
                  ,@IgnoreYear as IgnoreYear
                  ,5000 as IngnoreBalFwd WHERE (@IgnoreYear IS NULL OR @IgnoreYear <> '')
                              )
      SELECT * 
      FROM cteIgnoreCommID
      

      如果@IgnoreYear 从不为NULL,那么您可以删除“@IgnoreYear IS NULL OR”部分。

      【讨论】:

        【解决方案4】:

        我对 SQL 相当陌生,但我的问题的答案最终不是创建 CTE,而是创建一个临时表。这很好地处理了我的 IF 语句,我可以按照报告参数的要求将数据加入到它中。我用来创建空白临时表或填充临时表的代码是:

        create table #tmpIgnoreComm
            ( IgnoreComm_ID varchar(8)
             ,IgnoreYear varchar(4)
             ,IngnoreBalFwd numeric  )
        If @IgnoreYear<>''
            insert into #tmpIgnoreComm
                --(IgnoreComm_ID,IgnoreYear,IngnoreBalFwd)
            Select * 
            From 
            (   Select Distinct
                -- Long code to retrieve data
            ) data
        

        感谢大家的意见。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-11-22
          • 1970-01-01
          • 2019-05-06
          • 2010-11-12
          • 2011-08-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多