PL/SQL ORA-01422:精确提取返回的行数超过了请求的行数

Posted

技术标签:

【中文标题】PL/SQL ORA-01422:精确提取返回的行数超过了请求的行数【英文标题】:PL/SQL ORA-01422: exact fetch returns more than requested number of rows 【发布时间】: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;
/

【问题讨论】:

【参考方案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】:

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

【讨论】:

很高兴您想提供帮助,但是您的回答很简短,并且没有添加任何尚未说明的内容。下次请仔细阅读已经存在的任何答案。

以上是关于PL/SQL ORA-01422:精确提取返回的行数超过了请求的行数的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL ORA-01422 SELECT INTO 错误,Oracle 匿名块(NOVA 环境)

Oracle - ORA-01422:精确提取返回的行数超过了请求的行数

获取 ORA-01422 的原因:精确提取返回的行数超过了请求的行数

需要 ORA-01422 的解决方案:精确提取返回的行数超过请求的行数

ORA-01422:- ORA-06512:

我在编程中不断遇到此问题