Почему ошибка Oracle SELECT INTO выдает ошибку?

Я пишу код для создания процедуры в Oracle, она успешно создана, но когда RUN от разработчика SQL для просмотра вывода, это ошибка шоу.

ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "TESTUSER.USER_FEEDBACK", line 5
ORA-06512: at line 2

код:

create or replace PROCEDURE user_feedback
IS
initiator VARCHAR2(50);
BEGIN
select first_name into initiator
from person_info;
END ;

Пожалуйста, предложите мне.

2 ответа

ORA-01422: точная выборка возвращает больше запрошенного количества строк

select first_name into initiator
from person_info;

Сообщение об ошибке довольно ясно. Ваш оператор SELECT выше возвращает более 1 строки, однако вы пытаетесь извлечь несколько строк в скалярную переменную. Вы могли бы использовать SELECT INTO только для одного ряда. Для нескольких строк вам нужно использовать коллекции.

  • Либо используйте предикат фильтра, чтобы вернуть только одну строку
  • Или используйте коллекцию для хранения нескольких строк.

Например, используя стандартную таблицу EMP в схеме SCOTT:

SQL> DECLARE
  2  v_empno NUMBER;
  3  BEGIN
  4  SELECT empno INTO v_empno FROM emp;
  5  END;
  6  /
DECLARE
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 4

Давайте добавим фильтр WHERE ename = 'SCOTT' вернуть только одну строку:

SQL> DECLARE
  2  v_empno NUMBER;
  3  BEGIN
  4  SELECT empno INTO v_empno FROM emp WHERE ename = 'SCOTT';
  5  END;
  6  /

PL/SQL procedure successfully completed.

Давайте рассмотрим пример нескольких строк с использованием REFCURSOR.

Например,

SQL> var r refcursor
SQL> begin
  2     open :r for select empno from emp;
  3  end;
  4  /

PL/SQL procedure successfully completed.

SQL> print r

     EMPNO
----------
      7369
      7499
      7521
      7566
      7654
      7698
      7782
      7788
      7839
      7844
      7876
      7900
      7902
      7934

14 rows selected.

@ Лалит Кумар Б дал хороший ответ.

Мое дополнение - в PLSQL есть разные способы доступа к нескольким строкам - вообще говоря, вы можете использовать неявные или явные курсоры. Упомянутые выше REFCURSORS - это переменные, которые указывают на курсор, поэтому вы можете копировать их между частями кода.

Пример для неявного курсора (в вашем случае) будет -

CREATE OR REPLACE PROCEDURE user_feedback AS
BEGIN
   for c_name in select first_name from person_info loop
      /* do what ever you like with c, e.g - */
      insert into other_table (name) values (c.first_name);
      dbms_output.put_line(c.first_name);
   end loop;
END;
/

Явное использование курсора будет выглядеть так:

CREATE OR REPLACE PROCEDURE user_feedback AS
 cursor c_name is
  select first_name from person_info;
 l_name person_info.first_name%type;
BEGIN
 open c_name;
 while c_name%found loop
  fetch c_name into l_name;
  insert into other_table (name) values (c_name.first_name);
  dbms_output.put_line(c_name.first_name);
 end loop;
END;
/
Другие вопросы по тегам