【问题标题】:ORACLE Error report ORA-01422: exact fetch returns more than requested number of rows?ORACLE 错误报告 ORA-01422:精确提取返回的行数超过请求的行数?
【发布时间】:2020-10-29 15:02:07
【问题描述】:

我正在尝试运行以下代码,但它给了我错误。我是 ORACLE 的新手,欢迎任何帮助,还可以对代码进行哪些添加以确保将来捕获此错误并为用户提供有意义的消息谢谢。

DECLARE
      V_lname  VARCHAR2(15);
BEGIN
      SELECT last_name INTO v_lname
       FROM employees
       WHERE first_name='John';
       DBMS_OUTPUT.PUT_LINE  ('John' 's last name is : ' 
|| v_lname);

END;    

我遇到了这个错误;

错误报告 ORA-01422: 精确提取返回的行数多于请求的行数 ORA-06512: 在第 4 行

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    错误消息很清楚,您只能将一个值提取到您的 v_lname 变量中,因此 PL/SQL 错误地表示您的查询试图返回多行。

    要么:

    • 更改查询,使其只返回一行
    • 更改 PL/SQL 使其可以处理多行。

    我将演示第二个选项,因为我不知道您可能想要哪个名为“John”的员工。

    begin
      for rJohn in 
        (select last_name
         from   employees
         where  first_name='John'
        ) loop
          dbms_output.put_line  ('John''s last name could be : '|| rJohn.last_name);
       end loop;
    end;
    /    
    

    在这里,我使用隐式游标 for 循环 (https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/cursor-FOR-LOOP-statement.html#GUID-62C9A3C8-82F9-468F-8D84-81672E67736D) 为它为您的查询找到的每一行运行 dbms_output.put_line 调用。

    【讨论】:

      【解决方案2】:

      两个无用选项。为什么没用?因为您可能应该重写查询,以便它只返回所需的“John”。

      另外,一个建议:让变量引用列的数据类型,不要将其修复为例如varchar2(15)。如果您 - 在未来的某一天 - 必须更改表格并将列扩大到 varchar2(25) 怎么办?您的代码将惨遭失败。


      第一种选择:使用聚合函数,如MINMAX

      DECLARE
        V_lname  employees.last_name%type;            --> this
      BEGIN
        SELECT MAX(last_name)                         --> this
          INTO v_lname
          FROM employees
          WHERE first_name = 'John';
      
        DBMS_OUTPUT.PUT_LINE  ('John' 's last name is : ' || v_lname);
      END;    
      

      另一种选择是使用ROWNUM

      DECLARE
        V_lname  employees.last_name%type;            --> this
      BEGIN
        SELECT last_name
          INTO v_lname
          FROM employees
          WHERE first_name = 'John'
            AND rownum = 1;                           --> this
      
        DBMS_OUTPUT.PUT_LINE  ('John' 's last name is : ' || v_lname);
      END;    
      

      【讨论】:

        猜你喜欢
        • 2015-09-24
        • 1970-01-01
        • 1970-01-01
        • 2019-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-15
        相关资源
        最近更新 更多