Получить определенные поля из sys_refcursor в хранимой процедуре?

Я использую сервер Oracle 9i в своем офисе. Я работаю над процедурой, которая передает sys_refcursor в качестве параметра out в другой пакет (вместе с другими параметрами in). Мне удалось определить тип как запись различных столбцов, которые вызываемая процедура возвращает в курсоре. Затем я могу выполнить цикл с таким кодом:

LOOP
   fetch o_results into v_rec;
   exit when o_results%notfound;
   dbms_output.put_line(v_rec.some_id);
end loop;

Есть ли способ вывести только один столбец и не объявлять весь тип строки? Я пробовал что-то вроде:

LOOP
  fetch o_results.some_id into v_id;
  exit when o_results%notfound;
  dbms_output.put_line(v_id);
end loop;

Но это не сработало. Есть другие идеи?


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


Ответы (1)


Нет, вы не можете извлечь один столбец в локальную переменную, отличную от записи, если курсор возвращает набор результатов с несколькими столбцами. Однако у вас есть несколько альтернатив.

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

create or replace procedure cursor_proc
as
  cursor emp_cur
      is
   select empno, ename
     from emp;
  l_row emp_cur%rowtype;
begin
  open emp_cur;
  loop
    fetch emp_cur into l_row;
    exit when emp_cur%notfound;
    dbms_output.put_line( l_row.ename );
  end loop;
  close emp_cur;
end;

В качестве альтернативы, если вы знаете, что слабо типизированный указатель ref всегда будет возвращать все столбцы в конкретном объекте, вы можете привязать объявление локальной переменной к этому объекту. Вы всегда можете сделать это, объявив представление, из которого выбирает курсор. Например

create or replace view vw_emp
as
select ename, empno
  from emp

create or replace procedure cursor_proc2
as
  emp_cur sys_refcursor;
  l_row   vw_emp%rowtype;
begin
  open emp_cur for select * from vw_emp;
  loop
    fetch emp_cur into l_row;
    exit when emp_cur%notfound;
    dbms_output.put_line( l_row.ename );
  end loop;
  close emp_cur;
end;

Наконец, если вы используете неявный курсор, Oracle неявно объявит тип коллекции

create or replace procedure cursor_proc3
as
begin
  for emp in (select ename, empno from emp)
  loop
    dbms_output.put_line( emp.ename );
  end loop;
end;
person Justin Cave    schedule 18.05.2011