在存储过程中使用WITH

时间:2011-04-07 13:09:06

标签: sql stored-procedures select db2

我试图在存储过程中使用WITH但是失败了。我的假设是我可以使用WITH作为SELECT声明的一部分;现在我不确定是否可能,我做错了,或者是不可能。

我已经尝试了以下两种情况,但在AS

之后的WITH都抛出了错误

尝试1:

SET p_temp = (
    WITH
        temp (id) AS (
            SELECT orgs.id
            FROM orgstruct.tOrgs AS orgs
            WHERE orgs.prnt = p_OrgID
        )
    SELECT 1
    FROM temp
    FETCH FIRST 1 ROWS ONLY);

尝试2:

IF EXISTS (
        WITH
            temp (id) AS (
                SELECT orgs.id
                FROM orgstruct.tOrgs AS orgs
                WHERE orgs.prnt = p_OrgID
            )
        SELECT 1
        FROM temp) THEN
    SET p_temp = 1;
END IF;

是我通常想要使用的每个WITH创建视图的唯一解决方案吗?

3 个答案:

答案 0 :(得分:1)

我最终选择了以下内容:

DECLARE p_exists SMALLINT;

DECLARE c1 CURSOR
    WITHOUT HOLD
    WITHOUT RETURN
    FOR
        WITH
            cte AS (SELECT x FROM y)
        SELECT 1
        FROM cte
        FETCH FIRST 1 ROWS ONLY
    FOR READ ONLY
    OPTIMIZE FOR 1 ROWS;
OPEN c1;
SET p_exists = 0;
FETCH c1 INTO p_exists;
CLOSE c1;
如果存在一条或多条记录,则

p_exists为1,否则为0。 我原本希望避免使用光标,但它仍然比观看更好。

答案 1 :(得分:1)

怎么样

with cte as
(
SELECT COUNT(orgs.id) as cte_result 
            FROM orgstruct.tOrgs AS orgs
            WHERE orgs.prnt = p_OrgID
) 
select 
    case 
        when cte.cte_result > 0 
            then '>0' 
        else '=0' 
    end
from cte

返回'> 0'或'= 0'作为结果。

绝对不需要观看或游标......

答案 2 :(得分:0)

如果你的表达式实际上只是根据匹配行的存在返回标量值,那么可以在存储过程中完成,而不使用CTE:

SELECT CASE WHEN ( EXISTS (SELECT 1 FROM orgstruct.tOrgs AS orgs WHERE orgs.prnt = p_OrgID ) )
    THEN 1 
    ELSE 0 
    END 
INTO p_exists
FROM sysibm.sysdummy1
;

对于确实需要CTE的更复杂的查询,您还可以选择将CTE嵌入到用户定义的函数中,然后从存储过程中调用该函数。