2

我在 oracle 中编写了一个创建过程的代码,它已成功创建,但是当从 sql developer 运行以查看输出时,它显示错误。

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 ;

请给我建议。

4

2 回答 2

4

ORA-01422: 精确提取返回的行数多于请求的行数

select first_name into initiator
from person_info;

错误信息非常清楚。您上面的SELECT语句返回多于 1 行,但是,您试图将多行提取到scalar variable中。您SELECT INTO只能用于单行。对于多行,您需要使用collections

  • 要么使用过滤谓词仅返回单行
  • 或者,使用一个集合来保存多行。

例如,在 SCOTT 模式中使用标准 EMP 表:

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.
于 2015-12-24T12:06:51.973 回答
0

@Lalit Kumar B 给出了一个很好的答案。

我的补充——在 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;
/
于 2015-12-24T19:10:45.373 回答