如何在CTE中执行If语句

时间:2019-01-23 18:13:37

标签: tsql ssrs-2012

我需要根据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个错误:

  

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

4 个答案:

答案 0 :(得分: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
     )

答案 1 :(得分:0)

您可以将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

答案 2 :(得分:0)

您可以执行以下操作:

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”部分。

答案 3 :(得分:0)

我对SQL还是很陌生,但是对我的问题的答案最终是不是创建CTE而是创建临时表。这样可以很好地处理我的IF语句,并且可以根据report参数的要求将其与数据连接起来。我用来创建空白临时表或填充临时表的代码是:

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

感谢大家的输入。