sql >> Databasteknik >  >> RDS >> Oracle

Varför kan vi inte använda stark ref-markör med dynamisk SQL-sats?

Här är en procedur med en starkt skriven ref-markör:

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>

Denna nästa sats misslyckas eftersom signaturen för EMP-posten inte matchar den för DEPT-tabellen.

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>

Men om vi ändrar projektionen så att den matchar DEPT-tabellen har vi framgång igen:

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>

Så varför kan vi inte använda en starkt skriven ref-markör med dynamisk 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>

Eftersom kompilatorn inte kan analysera strängen i den dynamiska SQL-satsen. Så det kan inte hävda att kolumnerna i frågans projektion matchar i antal och datatyp signaturen för ref-markören. Följaktligen kan den inte validera kontraktet mellan ref-markörvariabeln och frågan. Det är ännu lättare att förstå varför detta inte kan tillåtas när vi tänker på att den dynamiska SQL-satsen kan sammanställas från en fråga på USER_TAB_COLUMNS.



  1. Hur filtrerar man rader på kapslade värden i en json-kolumn?

  2. Scala och MySQL JDBC-drivrutin

  3. Ska jag använda MySQL blob-fälttyp?

  4. Kör rails-kod efter att en uppdatering av databasen har genomförts, utan after_commit