存储过程中的 SQL with 子句

问题描述 投票:0回答:3

是否可以在存储过程中定义 with 子句并在 if else 语句中使用它,因为我总是收到错误?

BEGIN
    WITH Test (F, A) AS
    (
        SELECT FM.ID, FM.Name 
        FROM [Test.Abc] FM
        INNER JOIN [Organization] O on O.ABCID = FM.ID
    )

    IF(@var = 'case1')
    BEGIN
        SELECT * 
        FROM Test F
        WHERE NOT F.ID = 'someID'
    END

在 if 语句之前我总是收到“语法错误”错误

如果我将 with 子句移到 if 语句中,它就可以正常工作。但我需要外部的 with 语句才能在不同的 if else 语句中重用它。

sql sql-server common-table-expression with-statement
3个回答
3
投票

这是您得到的相同答案的另一个版本:

您的

with
common table expresson
必须与调用它的查询位于同一语句中,并且它必须由查询(或其他
cte
)引用,否则就是语法错误。

请参阅文档指南创建和使用公用表表达式

BEGIN -- doing stuff
-- .... doing stuff over here
IF(@var = 'case1')
    BEGIN
        with Test (F, A) as ( -- You define columns ID as F and Name as A
        select FM.ID, FM.Name from [Test.Abc] FM
        inner join [Organization] O on O.ABCID = FM.ID
          )     
        select * from Test 
        where not F = 'someID' -- You must use the new columna name (F)
    END
-- .... and doing some other stuff over here too
END -- done with this stuff

2
投票

只需使用临时表或表变量即可。 SQL Server 的作用域规则确保在过程结束时删除这样的表:

BEGIN
    select FM.ID, FM.Name
    into #test
    from [Test.Abc] FM inner join
         [Organization] O
         on O.ABCID = FM.ID;

    IF(@var = 'case1')
        BEGIN
            select *
            from #Test F
            where not F.ID = 'someID'
        END;

这样做的好处是您可以向表添加索引,这可能会提高性能。


1
投票

WITH 不是一个独立的语句,它始终是整个语句的一部分,并且只是一个语句。
在其声明范围之外是无法识别的。

BEGIN

    with my_cte (n) as (select 1+1)
    select * from my_cte

    -- The following statement yields the error "Invalid object name 'my_cte'."    
    -- select * from my_cte

END
© www.soinside.com 2019 - 2024. All rights reserved.