I need to pass a locally defined table type to a function which is a pipelined function returning another locally defined table type.
Here is sample data:
create table my_tab
(i NUMBER,
n VARCHAR2(30));
insert into my_tab values (1, 'Peter');
insert into my_tab values (2, 'Dakshesh');
insert into my_tab values (1, 'Maggie');
insert into my_tab values (3, 'Madhu');
commit;
My code is:
CREATE OR REPLACE PACKAGE my_pkg IS
TYPE t_col IS RECORD(
i NUMBER,
n VARCHAR2(30));
TYPE t_nested_table IS TABLE OF t_col;
TYPE t_number IS TABLE OF NUMBER;
FUNCTION iterate_table RETURN t_number PIPELINED;
FUNCTION return_table(in_t_num t_number) RETURN t_nested_table PIPELINED;
g_number t_number ;
g_nested_number t_nested_table ;
END my_pkg;
/
Body:
CREATE OR REPLACE PACKAGE BODY my_pkg IS
FUNCTION iterate_table RETURN t_number PIPELINED IS
BEGIN
IF ( (g_number IS NOT NULL) AND (g_number.EXISTS (1)))
THEN
FOR i IN 1 .. g_number.COUNT
LOOP
IF g_number (i) IS NOT NULL
THEN
PIPE ROW (g_number (i));
END IF;
END LOOP;
END IF;
RETURN;
EXCEPTION
WHEN OTHERS
THEN
RAISE;
END iterate_table;
FUNCTION return_table(in_t_num t_number) RETURN t_nested_table PIPELINED IS
l_row t_nested_table ;
CURSOR cur_test IS
select mt.i, mt.n
from my_tab mt, TABLE(iterate_table ) tab
where mt.i = tab.column_value;
BEGIN
OPEN cur_test;
FETCH cur_test BULK COLLECT into l_row;
CLOSE cur_test;
FOR i IN 1..l_row.COUNT
LOOP
PIPE ROW(l_row(i));
END LOOP;
RETURN;
END return_table;
END my_pkg;
/
Now this code compiles successfully, when I try to invoke it like a pipelined function, it gives error-
select * from table(my_pkg.return_table(my_pkg.t_number(1)));
Error-
ORA-00902: invalid datatype
00902. 00000 - "invalid datatype"
*Cause:
*Action:
Error at Line: 14 Column: 41
The two pre-requisites for this code are -
the collections should be all locally defined.
the function should be pipelined.
Help!!
I am not getting any error with table and its a single table so no foreign key constraints hold.
It is not possible in oracle 11. I don't know why oracle throws "invalid data type".
If you put this query into anonymous block you will receive PLS-00642: Local Collection Types Not Allowed in SQL Statement
If you don't want or you cannot create sql level collection. The solution is use predefined type. Good source of predefined collection is Oracle Data Cartridge
. Replace all t_number
with ODCINumberList
.