2016-10-21 13 views
4

私は次のようにネストした表を作成しました:PL SQLテーブルにネストされたテーブルから値を取得する方法

CREATE OR REPLACE TYPE EMP_NO_NAME 
AS OBJECT 
( 
EMPNO NUMBER(4), 
ENAME VARCHAR2(20), 
JOB VARCHAR2(20), 
MGR NUMBER(5), 
HIREDATE DATE, 
SAL NUMBER(7,2) 
); 
CREATE OR REPLACE TYPE EMP_TABLE IS TABLE OF EMP_NO_NAME; 

----------------------- 
CREATE TABLE NESTED_EMP 
(
DEPTNO NUMBER(2) , 
EMPLOYEE EMP_TABLE 
) 
NESTED TABLE EMPLOYEE STORE AS NESTED_EMPLOYEE; 

INSERT INTO NESTED_EMP (DEPTNO,EMPLOYEE) 
VALUES (10,EMP_TABLE(EMP_NO_NAME(7839,'KING','PRESIDENT',NULL,'17-NOV-81',5000), 
        EMP_NO_NAME(7782,'CLARK','MANAGER',7839,'09-JUN-81',2450), 
        EMP_NO_NAME(7934,'MILLER','CLERK',7782,'23-JAN-82',1300) 
        ) 
     ); 

INSERT INTO NESTED_EMP (DEPTNO,EMPLOYEE) 
VALUES (20,EMP_TABLE(EMP_NO_NAME(7566,'JONES','MANAGER',7839,'02-APR-81',2975), 
         EMP_NO_NAME(7902,'FORD','ANALYST',7566,'03-DEC-81',3000), 
         EMP_NO_NAME(7369,'SMITH','CLERK',7902,'17-DEC-80',800), 
         EMP_NO_NAME(7788,'SCOTT','ANALYST',7566,'09-DEC-82',3000), 
         EMP_NO_NAME(7876,'ADAMS','CLERK',7788,'12-JAN-83',1100) 
        ) 
     ); 
INSERT INTO NESTED_EMP (DEPTNO,EMPLOYEE) 
VALUES (20,EMP_TABLE(EMP_NO_NAME(7698,'BLAKE','MANAGER',7839,'01-MAY-81',2850), 
        EMP_NO_NAME(7654,'MARTIN','SALESMAN',7698,'28-SEP-81',1250), 
        EMP_NO_NAME(7499,'ALLEN','SALESMAN',7698,'20-FEB-81',1600), 
        EMP_NO_NAME(7844,'TURNER','SALESMAN',7698,'08-SEP-81',1500), 
        EMP_NO_NAME(7900,'JAMES','CLERK',7698,'03-DEC-81',950), 
        EMP_NO_NAME(7521,'WARD','SALESMAN',7698,'22-FEB-81',1250) 
        ) 
    ); 

は、今私はPLSQLでネストした表の値を取得:

DECLARE 
    CURSOR EMPLOYEE IS 
    select p.* from NESTED_EMP p1 ,table(p1.employee) p; 
    V_EMP EMP_TABLE; 
    BEGIN 
    FOR V_EMP IN EMPLOYEE 
    LOOP 
    EXIT WHEN EMPLOYEE%NOTFOUND; 
    END LOOP; 
    FOR MYINDEX IN V_EMP.FIRST..V_EMP.LAST 
    LOOP 
    DBMS_OUTPUT.PUT_LINE(V_EMP(MYINDEX).ENAME); 
    END LOOP; 
    END; 
    /
END; 

エラーレポートを:

ORA-06531:初期化されていないコレクションORA-06512への参照: 06531. 00000行10時 - "初期化されていないコレクションへの参照"

*原因:ネストした表またはVARRAY の要素またはメンバー関数が参照されています(初期化されたコレクションが必要な場合) コレクションは初期化されていません。

*処置:適切なコンストラクタ またはオブジェクト全体の割り当てを使用してコレクションを初期化してください。

どのようにplsql表のネストした表の値を取得するには?

+0

これはきちんと述べられた質問でした。シナリオを完全に再現するためのDDLの提供は非常に役に立ちます。 – Allan

答えて

2

コードの問題点は、V_EMPは実際にはEMP_TABLEではありません。むしろ、それはEMPLOYEE.ROWTYPEです。ループのカーソルを初期化すると、変数は自動的に適切なROWTYPEになり、以前の宣言が上書きされます。

クエリですでにネストしたテーブルを参照しているので、ループ内で既にネストしたテーブルを参照しているので(既に展開されています)、よいニュースです。あなたのPL/SQLを大幅に簡略化することができます:あなたはEXIT WHENが同様に削除された気づく

DECLARE 
    CURSOR employee IS 
     SELECT p.* 
     FROM nested_emp p1 CROSS JOIN TABLE (p1.employee) p; 
BEGIN 
    FOR v_emp IN employee LOOP 
     DBMS_OUTPUT.put_line (v_emp.ename); 
    END LOOP; 
END; 
/

。ループのカーソルは、最後のレコードの後に​​自動的に終了します。


代わりに、クエリ内のネストしたテーブルを分解しないようにすることもできます。次に、2つのループが必要です。

DECLARE 
    CURSOR employee IS 
     SELECT p.* 
     FROM nested_emp p; 
BEGIN 
    FOR v_emp IN employee LOOP 
     for i in v_emp.employee.first..v_emp.employee.last loop 
     DBMS_OUTPUT.put_line (v_emp.employee(i).ename); 
     end loop; 
    END LOOP; 
END; 
/
+0

は、plsqlブロックでネストした表の値を取得する他の方法です – shashank

関連する問題