sql >> Databáze >  >> RDS >> Oracle

Proč nemůžeme použít silný referenční kurzor s dynamickým příkazem SQL?

Zde je postup se silně napsaným referenčním kurzorem:

SQL> create or replace procedure p1 is
  2      type dept_rc is ref cursor return dept%rowtype;
  3      my_ref_cursor dept_rc;
  4  begin
  5      open my_ref_cursor for
  6          select * from dept;
  7  end;
  8  /

Procedure created.

SQL>

Tento další příkaz selže, protože podpis EMP záznamu neodpovídá podpisu tabulky DEPT.

SQL> create or replace procedure p1 is
  2      type dept_rc is ref cursor return dept%rowtype;
  3      my_ref_cursor dept_rc;
  4  begin
  5      open my_ref_cursor for
  6          select * from emp;
  7  end;
  8  /

Warning: Procedure created with compilation errors.

SQL> show error
Errors for PROCEDURE P1:

LINE/COL ERROR
-------- -----------------------------------------------------------------
5/5      PL/SQL: SQL Statement ignored
6/9      PLS-00382: expression is of wrong type

SQL>

Ale pokud změníme projekci tak, aby odpovídala tabulce DEPT, pak máme opět úspěch:

SQL> create or replace procedure p1 is
  2      type dept_rc is ref cursor return dept%rowtype;
  3      my_ref_cursor dept_rc;
  4  begin
  5      open my_ref_cursor for
  6          select deptno, ename, job from emp;
  7  end;
  8  /

Procedure created.

SQL>

Proč tedy nemůžeme použít silně typovaný ref-kurzor s dynamickým SQL?

SQL> create or replace procedure p1 is
  2      type dept_rc is ref cursor return dept%rowtype;
  3      my_ref_cursor dept_rc;
  4  begin
  5      open my_ref_cursor for
  6          'select * from dept';
  7  end;
  8  /

Warning: Procedure created with compilation errors.

SQL> show error
Errors for PROCEDURE P1:

LINE/COL ERROR
-------- -----------------------------------------------------------------
5/5      PL/SQL: Statement ignored
5/10     PLS-00455: cursor 'MY_REF_CURSOR' cannot be used in dynamic SQL
         OPEN statement

SQL>

Protože kompilátor nemůže analyzovat řetězec v dynamickém příkazu SQL. Nemůže tedy tvrdit, že se sloupce v projekci dotazu shodují v počtu a datovém typu s podpisem referenčního kurzoru. V důsledku toho nemůže ověřit smlouvu mezi proměnnou kurzoru ref a dotazem. Je ještě snazší pochopit, proč to nemůže být povoleno, když uvážíme, že dynamický příkaz SQL by mohl být sestaven z dotazu na USER_TAB_COLUMNS.



  1. nastavit identitu na sloupci

  2. Dynamický dotaz s HibernateCritera API &Oracle - výkon

  3. Vložení rodičovských/podřízených záznamů do transakce

  4. Co je LEFT JOIN v PostgreSQL