Ref cursor в коллекцию на лету


Маленький ночной бред на заданный вопрос на sql.ru:
Господа, подскажите, есть ли способ преобразовать реф.курсор в коллекцию 'налету' в селекте?
Т.е есть скажем объектный тип 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 - много, хотелось бы не городить на каждый по однотипной ф-ии,
а преобразовать прямо в селекте, либо обойтись одной универсальной ф-ией для всех типов курсоров.
Есть мысли, как?
В принципе задача идиотская, конечно, но захотелось побаловаться, поэтому и "набредил" извращение с коллекцией sys.anydata. А вообще, если иметь ввиду не только простые селекты объектов, а вообще на любые запросы, то их не обернуть так просто в anydata не заводя своего типа...
В общем, вот:
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

Отправить комментарий