Это другой способ, он выполняет почти все в запросе (обратите внимание, что для этого необходимо, чтобы типы создавались вне блока)
http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/05_colls.htm
Создание и очистка таблицы и используемых типов
/*
CREATE TABLE EMP (ENAME VARCHAR2(50) , DEPTNO NUMBER, empno number);
INSERT INTO EMP VALUES('m1e',1,1);
INSERT INTO EMP VALUES('m2e',1,2);
insert into emp values('m3e',2,3);
INSERT INTO EMP VALUES('m2e',2,4);
insert into emp values('m3e',3,5);
CREATE TABLE DEPT(deptno NUMBER, dname VARCHAR2(50), loc VARCHAR2(50));
INSERT INTO DEPT VALUES(1 ,'portland','tt');
INSERT INTO DEPT VALUES(2 ,'astoria','tt');
INSERT INTO DEPT VALUES(3 ,'eugene','tt');
Создание типов (обратите внимание, что это не входит в пакет / блок, чтобы он был доступен для SQL)
---
drop type emptable force;
DROP TYPE EMP_TAB_TYPE force;
drop type emptable ;
DROP TYPE DEPT_EMP_REC force;
drop type dep_emp_rec_table force;
DROP TABLE DEPT;
drop table emp;
*/
Теперь создайте типы вне пакета / блока, чтобы типы были доступны для SQL
create or replace TYPE emp_tab_type as object (ENAME VARCHAR2(50) , DEPTNO NUMBER);
create or replace type emptable as table of emp_tab_type ;
CREATE OR REPLACE TYPE DEPT_EMP_REC AS OBJECT (
DEPT_ID NUMBER,
dept_name varchar2(50),
dept_loc varchar2(50),
emp_data emptable);
create or replace type dep_emp_rec_table as table of dept_emp_rec;
Теперь мы можем напрямую выбирать типы в запросе (обратите внимание на использование cast / MULTISET )
SELECT
DEPT_EMP_REC(
deptno,
dname ,
loc ,
CAST(MULTISET(SELECT ENAME, DEPTNO
FROM EMP e
WHERE e.DEPTNO = d.deptno)
AS emptable))
FROM DEPT D ;
/
DEPT_EMP_REC(DEPTNO,DNAME,LOC,CAST(MULTISET(SELECTENAME,DEPTNOFROMEMPEWHEREE.DEPTNO=D.DEPTNO)ASEMPTABLE)) DEPT_EMP_REC(1,'portland','tt',EMPTABLE(EMP_TAB_TYPE('m1e',1),EMP_TAB_TYPE('m2e',1)))
DEPT_EMP_REC(2,'astoria','tt',EMPTABLE(EMP_TAB_TYPE('m3e',2),EMP_TAB_TYPE('m2e',2)))
DEPT_EMP_REC(3,'eugene','tt',EMPTABLE(EMP_TAB_TYPE('m3e',3)))
Теперь блок немного проще (собрать все вместе)
set serveroutput on
DECLARE
p_dep_emp_rec_table dep_emp_rec_table;
BEGIN
SELECT
DEPT_EMP_REC(
DEPTNO,
DNAME,
LOC,
CAST( MULTISET
(
SELECT
ENAME,
DEPTNO
FROM EMP E
WHERE E.DEPTNO = D.DEPTNO
) AS EMPTABLE )
)
BULK COLLECT INTO p_dep_emp_rec_table
FROM
DEPT d ;
FOR I IN P_DEP_EMP_REC_TABLE.FIRST..P_DEP_EMP_REC_TABLE.LAST LOOP
DBMS_OUTPUT.PUT_LINE(I || ':' || P_DEP_EMP_REC_TABLE(I).DEPT_ID || '|' || P_DEP_EMP_REC_TABLE(I).DEPT_NAME || '|' || P_DEP_EMP_REC_TABLE(I).DEPT_LOC);
DBMS_OUTPUT.PUT_LINE('-----------------------');
FOR J IN P_DEP_EMP_REC_TABLE(I).EMP_DATA.FIRST..P_DEP_EMP_REC_TABLE(I).EMP_DATA.LAST LOOP
NULL;
dbms_output.put_line(P_DEP_EMP_REC_TABLE(i).emp_data(j).ENAME || '/' || P_DEP_EMP_REC_TABLE(i).emp_data(j).DEPTNO);
end loop;
END LOOP;
END;
anonymous block completed
1:1|portland|tt
-----------------------
m1e/1
m2e/1
2:2|astoria|tt
-----------------------
m3e/2
m2e/2
3:3|eugene|tt
-----------------------
m3e/3