2010-05-06 96 views
2

我想用動態sql語句強大的引用當然,但它給出了一個錯誤,但是當我使用弱遊標它的作品,請解釋是什麼原因,請 轉發我的任何鏈接的Oracle服務器架構師有關Oracle服務器如何完成編譯和解析的問題。這是代碼錯誤。爲什麼我們不能在動態SQL語句中使用強引用?

ERROR at line 6: 
ORA-06550: line 6, column 7: 
PLS-00455: cursor 'EMP_REF_CUR' cannot be used in dynamic SQL OPEN statement 
ORA-06550: line 6, column 2: 
PL/SQL: Statement ignored 

declare 
     type ref_cur_type IS REF CURSOR RETURN employees%ROWTYPE; --Creating a strong REF cursor,employees is a table 
    emp_ref_cur ref_cur_type; 
    emp_rec employees%ROWTYPE; 
BEGIN  
    OPEN emp_ref_cur FOR 'SELECT * FROM employees'; 
      LOOP 
        FETCH emp_ref_cur INTO emp_rec; 
        EXIT WHEN emp_ref_cur%NOTFOUND; 
      END lOOP;  
END; 

回答

8

這裏是一個強類型的引用遊標的過程:

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> 

所以,爲什麼我們不能用一個強類型的REF光標使用動態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

另一種可能性是聲明和定義一個記錄類型對象作爲查詢結果的容器。如果查詢是JOIN查詢,則返回來自多個連接表的列。

SQL> create or replace procedure p1 is 
    /* Declare you destination data structure row container */ 
    TYPE TestRecTyp IS RECORD (
     deptno varchar(50), 
     ename varchar(50), 
     job varchar(50) 
    ); 
    /* Define an instance of the record type */ 
    testrec TestRecTyp; 

    type dept_rc is ref cursor; /*return dept%rowtype;*/ 
    my_ref_cursor dept_rc; 
    begin 
     open my_ref_cursor for 'select deptno,ename,job from emp'; 
     LOOP 
      FETCH my_ref_cursor INTO testrec; 
     EXIT WHEN my_ref_cursor%NOTFOUND; 

      /* Do some operations with testrec*/ 

     END LOOP; 
    end; 

注意:您可以通過替換使用上述技術,在動態構造SQL查詢語句「選擇DEPTNO,爲ename,從EMP工作」,與諸如v_sql一個變量,並用內SQL語句更新該變量程序的主體。

相關問題