Используйте WITH внутри хранимой процедуры - PullRequest
2 голосов
/ 07 апреля 2011

Я пытаюсь использовать 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 ]

1 голос
/ 08 апреля 2011

Как насчет

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' в качестве результата.

Определенно не нужны представления или курсоры ...

1 голос
/ 07 апреля 2011

Я закончил со следующим:

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. Я надеялся избежать использования курсора, но он по-прежнему предпочтительнее представлений.

0 голосов
/ 21 апреля 2011

Если ваше выражение на самом деле просто возвращает скалярное значение, основанное на наличии совпадающих строк, это можно сделать внутри вашей хранимой процедуры без использования 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 в пользовательскую функцию, а затем вызвать функцию из хранимой процедуры.

...