2012-03-19 3 views
2

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

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; 
+0

Что такое T_CURSOR? Обычно я использую sys_refcursor, поскольку тип переменной содержит открытый курсор. –

+0

Что такое код ошибки? –

+0

T_CURSOR - это typedef курсора ref ... – Sam

ответ

4

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

for item in c_items loop 

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

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

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

1

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

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 
+0

спасибо, что исправлена ​​часть таблицы temp ... все еще проблема в том, что вы не можете извлечь элементы из курсора c_items для циклов, чтобы я мог даже заполнить эта таблица. – Sam

Смежные вопросы