Как обернуть хранимую процедуру Oracle в функцию, которая выполняется стандартным запросом SELECT? - PullRequest
1 голос
/ 14 мая 2009

Я выполняю следующие действия, но продолжаю получать сообщение об ошибке и не вижу проблемы:

1) Создайте пользовательский тип данных Oracle, представляющий столбцы базы данных, которые вы хотите получить:

CREATE TYPE my_object AS OBJECT
     (COL1       VARCHAR2(50),
      COL2       VARCHAR2(50),
      COL3       VARCHAR2(50));

2) Создайте другой тип данных, который является таблицей объекта, который вы только что создали:


    TYPE MY_OBJ_TABLE AS TABLE OF my_object;

3) Создайте функцию, которая возвращает эту таблицу. Также используйте предложение конвейера, чтобы результаты передавались по конвейеру обратно в вызывающий SQL, например:


    CREATE OR REPLACE
    FUNCTION MY_FUNC (PXOBJCLASS varchar2)
    RETURN MY_OBJ_TABLE pipelined IS
    TYPE ref1 IS REF CURSOR
    Cur1 ref1,
    out_rec_my_object := my_object(null,null,null);
    myObjClass VARCHAR2(50);
    BEGIN
    myObjClass := PXOBJCLASS
    OPEN Cur1 For ‘select PYID, PXINSNAME, PZINSKEY from PC_WORK where PXOBJCLass = ;1’USING myObjClass,
    LOOP
        FETCH cur1 INTO out_rec.COL1, out_rec.COL2, out_rec.COL3;
        EXIT WHEN Cur1%NOTFOUND;
        PIPE ROW (out_rec);
    END LOOP;
    CLOSE Cur1;
    RETURN;
    END MY_FUNC; 

ПРИМЕЧАНИЕ. В приведенном выше примере вы можете легко заменить оператор выбора вызовом другой хранимой процедуры, которая возвращает переменную курсора.

4) В вашем приложении вызовите эту функцию как табличную функцию, используя следующую инструкцию SQL:

select COL1, COL2, COL3 from TABLE(MY_FUNC('SomeSampletask'));

Ответы [ 3 ]

1 голос
/ 14 мая 2009

Нет необходимости использовать динамический sql (динамический sql всегда немного медленнее) и объявлено слишком много переменных. Также цикл for намного проще. Я переименовал аргумент функции из pxobjclass в p_pxobjclass.

Попробуйте это:

create or replace function my_func (p_pxobjclass in varchar2)
return my_obj_table pipelined
is 
begin
  for r_curl in (select pyid,pxinsname,pzinskey 
                 from   pc_work
                 where  pxobjclass = p_pxobjclass) loop
    pipe row (my_object(r_curl.pyid,r_curl.pxinsname,r_curl.pzinskey));          
  end loop;
  return; 
end; 

EDIT1:

Кстати, быстрее вернуть курсор ref вместо конвейерной функции, которая возвращает вложенную таблицу:

create or replace function my_func2 (p_pxobjclass in varchar2)
return sys_refcursor
is 
  l_sys_refcursor sys_refcursor; 
begin
  open l_sys_refcursor for 
    select pyid,pxinsname,pzinskey 
    from   pc_work
    where  pxobjclass = p_pxobjclass;
  return l_sys_refcursor;  
end;

Это быстрее, потому что создание объектов (my_object) занимает некоторое время.

0 голосов
/ 14 мая 2009

Может быть, я что-то здесь неправильно понимаю, но похоже, что вы хотите использовать VIEW.

0 голосов
/ 14 мая 2009

Я вижу две проблемы:

  1. Динамический запрос не работает таким образом, попробуйте это:

    'выберите PYID, PXINSNAME, PZINSKEY из PC_WORK, где PXOBJCLass =' ​​'' || PXOBJCLASS || '' ''

Вам не нужен myObjClass, и кажется, что все ваши кавычки неверны.

  1. Цитата "SomeSampletask" ...

    выберите COL1, COL2, COL3 из TABLE (MY_FUNC ('SomeSampletask'));

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...