Почему я получаю ошибку компиляции при использовании встроенной функции внутри предложения WITH в PL / SQL?

#oracle #plsql #common-table-expression

#Oracle #plsql #common-table-expression

Вопрос:

Есть новая функция, которая позволяет мне писать функцию PL / SQL, которая существует только на время выполнения инструкции, например:

     SQL> with function f return number is
      2  begin
      3    return 1;
      4  end;
      5  select f from dual;
      6  /
    
             F
    ----------
             1

It is in the documentation that to use this for DML (insert, update, delete) then I need the WITH_PLSQL hint.

    SQL> create table t ( x int );
    
    Table created.
    
    SQL>
    SQL> insert into t
      2  with function f return number is
      3  begin
      4    return 1;
      5  end;
      6  select f from dual;
      7  /
    with function f return number is
    *
    ERROR at line 2:
    ORA-32034: unsupported use of WITH clause
    
    SQL> insert /*  with_plsql */ into t
      2  with function f return number is
      3  begin
      4    return 1;
      5  end;
      6  select f from dual;
      7  /
    
    1 row created.

But if I try to add that INSERT command into a stored procedure, it will not compile.

SQL> create or replace
  2  procedure myproc is
  3  begin
  4  insert /*  with_plsql */ into t
  5  with function f return number is
  6  begin
  7    return 1;
  8  end;
  9  select f from dual;
 10  end;
 11  /

Warning: Procedure created with compilation errors.

SQL>
SQL> sho err
Errors for PROCEDURE MYPROC:

LINE/COL ERROR
-------- ---------------------------------------------------------
3/1      PL/SQL: SQL Statement ignored
4/15     PL/SQL: ORA-00905: missing keyword
8/1      PLS-00103: Encountered the symbol "SELECT"
 

Эта конструкция не разрешена в PL / SQL?

Ответ №1:

Это (текущее) ограничение для компилятора PL / SQL. Обходной путь заключается в использовании динамического SQL, чтобы оператор передавался в механизм SQL во время выполнения и пропускал фазу компиляции PL / SQL.

 SQL> create or replace
  2  procedure myproc is
  3  begin
  4  execute immediate '
  5  insert /*  with_plsql */ into t
  6  with function f return number is
  7  begin
  8    return 1;
  9  end;
 10  select f from dual';
 11
 12  end;
 13  /

Procedure created.

SQL>
SQL> exec myproc

PL/SQL procedure successfully completed.