Oracle
 sql >> база данни >  >> RDS >> Oracle

Защо не можем да използваме силен референтен курсор с динамичен 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  /

Procedure created.

SQL>

Този следващ оператор е неуспешен, защото подписът на EMP записа не съвпада с този на таблицата 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>

Но ако променим проекцията, за да съответства на таблицата 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 deptno, ename, job from emp;
  7  end;
  8  /

Procedure created.

SQL>

И така, защо не можем да използваме строго типизиран референтен курсор с динамичен 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>

Тъй като компилаторът не може да анализира низа в динамичния SQL оператор. Така че не може да твърди, че колоните в проекцията на заявката съвпадат по брой и тип данни на подписа на референтния курсор. Следователно не може да потвърди договора между променливата на референтния курсор и заявката. Още по-лесно е да разберем защо това не може да бъде разрешено, когато смятаме, че динамичният SQL израз може да бъде сглобен от заявка в USER_TAB_COLUMNS.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на Java за свързване към база данни на Oracle

  2. Как да изпълня съхранена процедура от SQL Plus?

  3. В тригер на Oracle мога ли да присвоя ново и старо към променлива тип ред?

  4. Известие за промени в таблицата на Oracle в Java

  5. Как да използвате Oracle SQL*Plus