Господа, подскажите, есть ли способ преобразовать реф.курсор в коллекцию 'налету' в селекте?В принципе задача идиотская, конечно, но захотелось побаловаться, поэтому и "набредил" извращение с коллекцией sys.anydata. А вообще, если иметь ввиду не только простые селекты объектов, а вообще на любые запросы, то их не обернуть так просто в anydata не заводя своего типа...
Т.е есть скажем объектный тип MY_TYPE_1, коллекция MY_TYPE_COLL_1 IS TABLE OF MY_TYPE1
и курсор:
OPEN CURS FOR
SELECT MY_TYPE_COLL_1( MY_TYPE_1(1), MY_TYPE_1(2) ) FROM DUAL;
Хотелось бы в селекте преобразовать этот курсор в коллекцию, сейчас делаю это с помощью ф-ии
FUNCTION MakeColl_1(ACurs SYS_REFCURSOR) return MY_TYPE_COLL_1 IS
Res MY_TYPE_COLL_1;
BEGIN
FETCH ACurs BULK COLLECT INTO Res;
RETURN Res;
END;
Т.к как типов MY_TYPE_COLL_x - много, хотелось бы не городить на каждый по однотипной ф-ии,
а преобразовать прямо в селекте, либо обойтись одной универсальной ф-ией для всех типов курсоров.
Есть мысли, как?
В общем, вот:
create or replace type anydata_table as table of sys.anydata;
CREATE OR REPLACE TYPE MY_TYPE IS OBJECT (
field1 VARCHAR2(100),
field2 VARCHAR2(100),
field3 VARCHAR2(100))
/
create or replace function sys_refcursor_to_anydata_table(cur in sys_refcursor)
return anydata_table
is
l_anydata_table anydata_table;
begin
fetch cur bulk collect into l_anydata_table;
return l_anydata_table;
end sys_refcursor_to_anydata_table;
/
declare
l_cursor sys_refcursor;
l_table anydata_table;
l_my_type my_type;
begin
open l_cursor for
'select
sys.anydata.ConvertObject(my_type(level,level*2,level*3))
from dual
connect by level <=10';
l_table:=sys_refcursor_to_anydata_table(l_cursor);
for i in l_table.first..l_table.last
loop
if l_table(i).getObject(l_my_type) = dbms_types.SUCCESS then
case l_table(i).gettypename()
when user||'.MY_TYPE'
then
dbms_output.put_line( l_table(i).gettypename()||'('
||l_my_type.field1||','
||l_my_type.field2||','
||l_my_type.field3||')'
);
else
dbms_output.put_line('Unexpected type:'||l_table(i).gettypename());
end case;
end if;
end loop;
close l_cursor;
end;
Comments
Отправка комментария