为什么在 PL/SQL 的 WITH 子句中使用内联函数时会出现编译错误?

时间:2021-01-11 01:00:33

标签: 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 个答案:

答案 0 :(得分:2)

这是对 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.
相关问题