如何从pl sql表中的嵌套表中获取值

Posted

技术标签:

【中文标题】如何从pl sql表中的嵌套表中获取值【英文标题】:How to get value from nested table in pl sql table 【发布时间】:2017-03-03 23:47:41 【问题描述】:

我创建了如下嵌套表:

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:在第 10 行 06531. 00000 - “对未初始化集合的引用”

*原因:嵌套表或可变数组的元素或成员函数 被引用(需要初始化集合的地方) 没有初始化集合。

*Action:使用适当的构造函数初始化集合 或整个对象分配。

如何获取plsql表中的嵌套表值?

【问题讨论】:

这是一个很好的问题。提供 DDL 以完全重新创建场景非常有帮助。 【参考方案1】:

您的代码的问题是V_EMP 实际上不是EMP_TABLE 类型。相反,它是EMPLOYEE.ROWTYPE。当您为循环初始化游标时,该变量会自动成为适当的ROWTYPE,覆盖之前的任何声明。

好消息是,由于您已经在查询中引用了嵌套表,因此您不需要在循环中这样做(它已经被分解了)。您的 PL/SQL 可以大大简化:

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;
/

您会注意到EXIT WHEN 也被删除了。循环游标在最后一条记录后自动终止。


另一种方法是不在查询中展开嵌套表。然后你需要两个循环:

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;
/

【讨论】:

是在 plsql 块中获取嵌套表值的任何其他方式

以上是关于如何从pl sql表中的嵌套表中获取值的主要内容,如果未能解决你的问题,请参考以下文章

当嵌套表属于记录类型时,如何将数据填充到 Oracle 中的嵌套表中

无法将值存储到 oracle 中的嵌套表中

Lua - 从嵌套表中获取值

使用嵌套表在 Oracle PL/SQL 中构建动态 SQL

pl/SQL 过程从不同表中的值生成一个表中的值

如何将值插入到python中的嵌套表中?