Использовать курсор Oracle в Proc и вернуть его?

Я работаю над пакетом, который вернет два курсора. Один курсор представляет собой список элементов с числовым первичным ключом. Другой курсор представляет собой список файлов, связанных с элементами

Код пока:

procedure get_items_with_files(
           o_results out sys_refcursor,
           o_files out sys_refcursor
) is 
begin

   begin
      open o_results for
          select item_id,
                 item_name
          from items;
   end;

   begin
      open o_files for
           select item_id
                  item_file_name
           from item_files if
           where if.item_id in (select item_id from TABLE(CAST(o_results)));
   end;
end get_items_with_files;

Области, с которыми у меня возникают проблемы:

  1. Получение ошибки отсутствующего ключевого слова в разделе table (cast (cursor))
  2. Могу ли я получить доступ к курсору в коде, как я, или мне нужно скопировать его во внутреннюю переменную? Я попытался создать переменную типа sys_refcursor и «set v_cursor := o_results», но получил ошибку об отсутствующем или недопустимом параметре.

person SpaceCowboy74    schedule 01.03.2012    source источник


Ответы (1)


Вы не можете использовать курсор O_RESULTS, чтобы открыть курсор O_FILES.

Вы можете запросить таблицу ITEMS, чтобы открыть оба курсора, но это создает возможность того, что некоторые данные изменятся между открытием курсора O_RESULTS и временем открытия курсора O_FILES, и что два набора результатов не синхронизированы.

procedure get_items_with_files(
           o_results out sys_refcursor,
           o_files out sys_refcursor
) is 
begin

   begin
      open o_results for
          select item_id,
                 item_name
          from items;
   end;

   begin
      open o_files for
           select item_id
                  item_file_name
           from item_files if
           where if.item_id in (select item_id from items);
   end;
end get_items_with_files;

Гораздо чаще было бы возвращать один курсор, представляющий результат объединения двух таблиц.

procedure get_items_with_files(
           o_results out sys_refcursor
) is 
begin
  open o_results for
      select item_id,
             item_name,
             item_file_name
        from items
             join item_files using (item_id);
end get_items_with_files;

Однако, если все, что делает ваша процедура, — это открытие курсора, было бы более распространенным создать представление, а не процедуру, а затем запросить представление, а не вызывать процедуру.

person Justin Cave    schedule 01.03.2012
comment
Спасибо. В ожидании результата я повторно проанализировал код. Хотя мои фактические курсоры гораздо сложнее, чем в примерах, я понял, что могу просто сделать вложенный выбор в нужном мне поле из таблицы, которая меня интересует. - person SpaceCowboy74; 02.03.2012
comment
О, что касается нескольких курсоров, это потому, что я не могу вернуть несколько строк для каждого элемента в первом курсоре. Это требование один/один. Я мог бы, вероятно, сделать некоторые SQLfu и сделать список файлов с разделителями-запятыми, но я полагал, что конечный пользователь может просто использовать набор данных с двумя данными в долгосрочной перспективе. (есть несколько файлов на элемент) - person SpaceCowboy74; 02.03.2012