Почему ошибка 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;
/