Oracle 11g: использование курсоров внутри процедуры


Я пытаюсь вернуть два курсора 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 2

2 ответа:

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

for item in c_items loop

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

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

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

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

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