TransWikia.com

Невозможно поместить клаузу WITH FUNCTION в BEGIN/END блок

Stack Overflow на русском Asked on November 30, 2021

Почему не компилируется следующий код?

DECLARE c number;
BEGIN
    WITH FUNCTION calculate(i IN NUMBER) RETURN NUMBER AS
        r number;
    BEGIN
        r := i*i;
        RETURN r;
    END;
    select calculate(1) INTO c from dual;
END;
/

Ошибка компиляции:

Error report -
ORA-06550: line 3, column 19:
PL/SQL: ORA-00905: missing keyword
ORA-06550: line 3, column 5:
PL/SQL: SQL Statement ignored

Хотя сам запрос выполняется:

WITH FUNCTION calculate(i IN NUMBER) RETURN NUMBER AS
    r number;
BEGIN
    r := i*i;
    RETURN r;
END;
select calculate(1) from dual
/

CALCULATE(1)
------------
           1

Свободный перевод вопроса Unable to put a WITH FUNCTION clause in a BEGIN/END block от участника @user2672165

One Answer

Похоже, что эта конструкция еще не поддерживается в PL/SQL. Предположительно, она будет добавлена в одном из будущих релизов.

А пока, хотя не совсем красиво, но можно использовать динамический SQL, который выполнит рабочий запрос в SQL контексте, где он поддерживается:

declare c number;
begin
    execute immediate '
    WITH FUNCTION calculate(i IN NUMBER) RETURN NUMBER AS
        r number;
    BEGIN
        r := i*i;
        RETURN r;
    END;
    select calculate(1) from dual' into c;
    dbms_output.put_line ('result '||c);
end;
/

result 1

В документации PL/SQL Language Reference клауза WITH вообще не упомянута, хотя она уже работала для статических запросах в боле старых релизах. В SQL Language Reference нет упоминания об ограничении использовния в PL/SQL контексте.


Свободный перевод ответа от участника @Alex Poole

Answered by 0xdb on November 30, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP