Получить конкретные поля из sys_refcursor в хранимой процедуре? - PullRequest
0 голосов
/ 18 мая 2011

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

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;

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

1 Ответ

1 голос
/ 18 мая 2011

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

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

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;
...