Использование цикла For для извлечения нескольких строк в процедуре Oracle

Я работаю над хранимой процедурой, где мне нужно получить набор результатов и обработать каждый элемент по отдельности, а затем вернуть весь результат (используя 3 разные таблицы).

Я не слишком знаком с базами данных, но вот что я смог придумать.

create or replace procedure GET_EMP_RSLT
  IS

CURSOR ecursor IS select emp_id from temp_employee where 'some condition';

BEGIN

FOR empidset in ecursor  

  LOOP

  Select * from 

    (select * from payroll_info where emp_id = empidset.emp_id) a

    left join 

    (select * from benefit_info where emp_id = empidset.emp_id) b 
     on a.emp_id = b.emp_id    

  END LOOP;

END;

При выполнении я получаю следующую ошибку..

an INTO clause is expected in this SELECT statement : "Select * from"

кто-нибудь может объяснить, как исправить эту ошибку и получить требуемые результаты?

PS. Я использую Oracle 9i и TOAD 9

Спасибо,
Том


person tom    schedule 10.08.2010    source источник


Ответы (4)


SELECT внутри вашего цикла должен иметь предложение INTO для обработки значений - из вашего кода неясно, что вы пытаетесь сделать, но я подозреваю, что вложенные SELECT/JOIN внутри цикла курсора лучше записать как объединение трех таблиц в главном курсоре.

person dpbradley    schedule 10.08.2010
comment
+1, особенно за рекомендацию перемещать все выделения в главный курсор. Ваша рекомендация о том, что предложение INTO решит проблему, предполагает, что выбор внутри цикла возвращает только одну строку для каждой итерации над курсором, иначе вы получите ошибку ORA-1422. - person DCookie; 10.08.2010

Вам нужно добавить предложение INTO, чтобы указать, в какие локальные переменные помещать выбранные данные, например.

select ID, Name
  into myID, myName
from emp
person a'r    schedule 10.08.2010
comment
Предполагается, что выбор возвращает одну строку. - person DCookie; 10.08.2010

Ниже приведено возможное решение, делающее изрядное количество предположений. Как написано, он возвращает результат в виде курсора ref, содержащего данные из всех 3 таблиц (было бы тривиально заставить его возвращать курсор ref для каждой таблицы, но это было бы больше работы для сомнительного результата).

Однако, если вы действительно не делаете что-то в PL/SQL, чего вы не можете сделать в SQL, вам было бы гораздо лучше делать это непосредственно в SQL.

create object EMP_PAYROLL_BENEFIT as object (
   em_id number,
   some_payroll_column number,
   some_benefit_column number);

create type NT_EMP_PAYROLL_BENEFIT as table of EMP_PAYROLL_BENEFIT;

create or replace procedure GET_EMP_RSLT(p_output OUT sys_refcursor)  IS    
CURSOR ecursor IS select emp_id 
                  from temp_employee te 
                       join payroll_info pi 
                       on te.emp_id = pi.emp_id 
                       join benefit_info bi 
                       on te.emp_id = bi.emp_id 
                  where some_column = 'some condition';
v_results NT_EMP_PAYROLL_BENEFIT;
BEGIN
   open ecursor;
   fetch ecursor bulk collect into v_results;
   close ecursor;
   for i = v_results.first..v_results.last loop
      v_results.some_benefit_column := some_payroll_column + i;
   end loop;
   open p_output for select * from table(v_results);
end;
person Allan    schedule 10.08.2010

В вашем коде слишком много синтаксических и идеологических ошибок. Поэтому прочтите, пожалуйста, документацию по PL/SQL здесь, особенно раздел PL/SQL Architecture. чтобы понять разницу между SQL и PL/SQL (обычно SQL - язык запросов, PL/SQL - язык программирования) и разделы для вашего случая:

  1. "Понимание процедур PL/SQL" и "Понимание функций PL/SQL"< /а>
  2. "Циклы курсора FOR" и "Использование курсора FOR Loops"

Полный справочник по PL/SQL для Oracle 9i R2 доступен по адресу этой странице. ссылка.

Комплект всей документации по Oracle 9i R2 можно найти здесь.

person ThinkJet    schedule 11.08.2010