Oracle 11g: использование курсоров внутри процедуры - PullRequest
2 голосов
/ 19 марта 2012

Я пытаюсь вернуть два ref-курсора из процедуры, и у меня возникли проблемы.Я пытаюсь получить информацию из первого курсора, выбрать из нее несколько полей, присоединиться к другой информации и вставить результат в переменную таблицы ... затем выбрать отдельные элементы из этой таблицы во второйкурсор.Но я не могу заставить это скомпилировать.Может кто-нибудь сказать мне, что я делаю не так, пожалуйста?

type T_CURSOR is REF CURSOR

procedure FetchSL3Details_PRC
(
c_items out T_CURSOR,
c_identifiers out T_CURSOR,
p_niin in char
) as
v_idents IDENTIFIER_TABLE_TYPE:= IDENTIFIER_TABLE_TYPE();
BEGIN

open c_items for
  select
    its.item_set_id,
    its.niin,
    its.parent_niin,
    its.commodity_id,
    its.service_type,
    its.sl3_type,
    its.qty,
    its.created_id,
    its.created_dt,
    its.modified_id,
    its.modified_dt
  from
    item_set its
  start with its.niin = p_niin
  connect by prior its.niin = its.parent_niin;

  for item in c_items loop
    v_idents.extend;
    v_idents(v_idents.LAST) := identifier_row_type(item.commodity_id,
                                                      get_group_name_fun(item.commodity_id),
                                                      0);
    v_idents.extend;
    v_idents(v_idents.LAST) := identifier_row_type(item.created_id,
                                                      get_formatted_name_fun(item.created_id),
                                                      0);
    v_idents.extend;
    v_idents(v_idents.LAST) := identifier_row_type(item.modified_id,
                                                      get_formatted_name_fun(item.modified_id),
                                                      0);
  end loop;

  open c_identifiers for
    select 
      distinct(v.id),
      v.name,
      v.type
    from
      v_idents v;

END FetchSL3Details_PRC;

Ответы [ 2 ]

4 голосов
/ 19 марта 2012

Вы не можете использовать эту конструкцию:

for item in c_items loop

с REF CURSOR. Ожидается, что c_items будет стандартным PL / SQL CURSOR. Это непосредственная причина ошибки, которую вы получаете. Если вы хотите зациклить REF CURSOR, насколько я знаю, вам нужно использовать явные операторы FETCH и обрабатывать условие цикла самостоятельно.

Кроме того, то, что вы говорите, что пытаетесь сделать, не совсем имеет смысла. Если вы извлекаете курсор из курсора c_items в теле процедуры, возвращая его и вызывающей стороне, может привести к путанице. В своем комментарии вы используете фразу «выбрать в курсор», что подразумевает, что, возможно, вы думаете о курсоре как о статической коллекции, которую вы можете многократно повторять. Это не так - курсор представляет активный запрос в памяти. Как только строка извлекается из курсора, она не может быть получена снова.

Я не уверен, что именно предложить, поскольку я не понимаю конечной цели кода. Если вам действительно нужно обрабатывать строки из c_items и возвращать их как используемый REF CURSOR, тогда единственный вариант - закрыть и снова открыть его.

1 голос
/ 19 марта 2012

Изменить это:

open c_identifiers for
    select 
      distinct(v.id),
      v.name,
      v.type
    from
      v_idents v;

до:

open c_identifiers for
    select 
      distinct(v.id),
      v.name,
      v.type
    from
      TABLE(v_idents) v; -- Use TABLE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...