Ошибка в процедуре: PLS-00428: an INTO clause is expected in this SELECT

Есть процедура, которая возвращает откртытый курсор. Если I_ID IS NULL, то процедура должна возвращать все записи:

PROCEDURE GETPERSON(I_ID IN NUMBER, I_STARTDATE IN DATE,I_ENDDATE IN DATE, RC OUT SYS_REFCURSOR) IS--ADMINKA
    BEGIN
    IF I_ID IS NOT NULL THEN
    OPEN RC FOR
        SELECT
            NAME,
            AGE
        FROM PERSON S
       WHERE  S.ID = I_ID;
       ELSE
         SELECT NAME, AGE FROM PERSON;
      END IF;
    END GETPERSON;

Но выдает такую ошибку:

Error: PLS-00428: an INTO clause is expected in this SELECT

Что не так, и как можно исправить?


Ответы (1 шт):

Автор решения: 0xdb

В оператор открытия курсора OPEN-FOR нельзя передать два запроса по условию в IF-ELSE. Исправить можно так:

create or replace package body pack as
    procedure getperson (id number, rc out sys_refcursor) is
    begin
        open rc for 
            select * 
            from person s
            where s.id = coalesce (getperson.id, s.id);
    end getperson;
end;    
/

Package Body PACK compiled

Но так лучше не делать - это плохой дизайн. Прочтя имя процедуры и передаваемые ей параметры: "верни мне персону к заданнаму Id", никто не станет ожидать, что если Id неопределенно (null), то процедура вместо пустого результата вернёт все записи.

Поэтому, правильнее надо сделать так:

create or replace package pack as
    procedure getPerson (id number, rc out sys_refcursor);
    procedure getAllPersons (rc out sys_refcursor);
end;
/
create or replace package body pack as
    procedure getPerson (id number, rc out sys_refcursor) is
    begin
        open rc for 
            select * 
            from person s
            where s.id = getperson.id;
    end getperson;
    procedure getAllPersons (rc out sys_refcursor) is
    begin    
        open rc for select * from person;
    end getAllPersons;
end;    
/

Запустить тест и получить результат:

var rc refcursor
exec pack.getPerson (1, :rc);

        ID NAME                            
---------- --------------------------------
         1 aaa                             

exec pack.getAllPersons (:rc);

        ID NAME                            
---------- --------------------------------
         1 aaa                             
         2 bbb                             
         3 ccc                             

На db<>fiddle.

→ Ссылка