【问题标题】:PL/SQL ORA-01422: exact fetch returns more than requested number of rowsPL/SQL ORA-01422:精确提取返回的行数超过了请求的行数
【发布时间】:2013-11-15 18:22:51
【问题描述】:

我不断收到此错误,我无法弄清楚是什么问题。

声明
*
第 1 行出现错误:
ORA-01422: 精确提取返回的行数多于请求的行数
ORA-06512:在第 11 行

这是我的代码。

DECLARE
    rec_ENAME EMPLOYEE.ENAME%TYPE;
    rec_JOB EMPLOYEE.DESIGNATION%TYPE;
    rec_SAL EMPLOYEE.SALARY%TYPE;
    rec_DEP DEPARTMENT.DEPT_NAME%TYPE;
BEGIN       
    SELECT EMPLOYEE.EMPID, EMPLOYEE.ENAME, EMPLOYEE.DESIGNATION, EMPLOYEE.SALARY,  DEPARTMENT.DEPT_NAME 
    INTO rec_EMPID, rec_ENAME, rec_JOB, rec_SAL, rec_DEP 
    FROM EMPLOYEE, DEPARTMENT 
    WHERE EMPLOYEE.SALARY > 3000;

    DBMS_OUTPUT.PUT_LINE ('Employee Nnumber: ' || rec_EMPID);
    DBMS_OUTPUT.PUT_LINE ('---------------------------------------------------');
    DBMS_OUTPUT.PUT_LINE ('Employee Name: ' || rec_ENAME);
    DBMS_OUTPUT.PUT_LINE ('---------------------------------------------------');
    DBMS_OUTPUT.PUT_LINE ('Employee Designation: ' || rec_JOB);
    DBMS_OUTPUT.PUT_LINE ('----------------------------------------------------');
    DBMS_OUTPUT.PUT_LINE ('Employee Salary: ' || rec_SAL);
    DBMS_OUTPUT.PUT_LINE ('----------------------------------------------------');
    DBMS_OUTPUT.PUT_LINE ('Employee Department: ' || rec_DEP);

END;
/

【问题讨论】:

    标签: oracle plsql oracle11g sqlplus


    【解决方案1】:

    如果SELECT INTO 语句返回的不是 1 行,它将引发错误。如果它返回 0 行,你会得到一个 no_data_found 异常。如果它返回超过 1 行,您将收到 too_many_rows 异常。除非您知道总有 1 名员工的薪水高于 3000,否则您不希望在此处使用 SELECT INTO 声明。

    您很可能希望使用游标来迭代(可能)多行数据(我还假设您打算在两个表之间进行适当的连接,而不是进行笛卡尔积,所以我假设两个表中都有一个departmentID 列)

    BEGIN
      FOR rec IN (SELECT EMPLOYEE.EMPID, 
                         EMPLOYEE.ENAME, 
                         EMPLOYEE.DESIGNATION, 
                         EMPLOYEE.SALARY,  
                         DEPARTMENT.DEPT_NAME 
                    FROM EMPLOYEE, 
                         DEPARTMENT 
                   WHERE employee.departmentID = department.departmentID
                     AND EMPLOYEE.SALARY > 3000)
      LOOP
        DBMS_OUTPUT.PUT_LINE ('Employee Nnumber: ' || rec.EMPID);
        DBMS_OUTPUT.PUT_LINE ('---------------------------------------------------');
        DBMS_OUTPUT.PUT_LINE ('Employee Name: ' || rec.ENAME);
        DBMS_OUTPUT.PUT_LINE ('---------------------------------------------------');
        DBMS_OUTPUT.PUT_LINE ('Employee Designation: ' || rec.DESIGNATION);
        DBMS_OUTPUT.PUT_LINE ('----------------------------------------------------');
        DBMS_OUTPUT.PUT_LINE ('Employee Salary: ' || rec.SALARY);
        DBMS_OUTPUT.PUT_LINE ('----------------------------------------------------');
        DBMS_OUTPUT.PUT_LINE ('Employee Department: ' || rec.DEPT_NAME);
      END LOOP;
    END;
    

    我假设您也只是在学习 PL/SQL。在实际代码中,您永远不会像这样使用dbms_output,也不会依赖任何人看到您写入dbms_output 缓冲区的数据。

    【讨论】:

    • 谢谢,但我必须保留所有这些“DBMS_OUTPUT”行,然后使用“SET SERVEROUTPUT ON”来显示结果。正确的方法是什么?我正在学习的书正在教我这样做。两个表中都有一个部门 ID 列,但我需要只在部门表中的部门名称。是的,我是 PL/SQL 的新手,我正在学习它作为我本科信息系统专业的数据库编程课程的一部分。
    • 并不是DBMS_OUTPUT不正确,而是导师和教程作者的那种绕过。 Dbms_Output 不产生任何输出。它创建一个缓冲区,客户端可以处理(读取)该客户端是否是 sqlplus、IDE、Java 应用程序/程序、Web 服务……同样客户端可以忽略它。问题是大多数生产应用程序/服务只是忽略它。它确实允许创建消息来向您展示您的流程正在做什么以及价值观。因此,它是一个有用的学习和调试工具。但在实时应用中用处不大。
    • 有关更多信息,请参阅DBMS_OUTPUT 文档和/或搜索 dbms_output.get_line。
    【解决方案2】:

    这也可能是由于所使用的任何表中存在重复条目。

    【讨论】:

    • 很高兴您想提供帮助,但是您的回答很简短,并且没有添加任何尚未说明的内容。下次请仔细阅读已经存在的任何答案。
    猜你喜欢
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 2015-09-24
    • 1970-01-01
    相关资源
    最近更新 更多