首页 > 解决方案 > 子查询在 PL/SQL 存储过程中连续返回多个

问题描述

我是 PL/SQL 的完全新手,这是开始编写存储过程的尝试。案例是我想在我的存储过程中简单地找出在特定部门获得最高薪水的员工的姓名是什么(作为参数传递给存储过程)。

下面是我的表格的屏幕截图:

部门表

员工表

我的存储过程的代码如下:

create or replace procedure High_salary(Dept_Name IN varchar2)
/*RETURN varchar2 */
AS
EMP_NAME_var varchar2(100) := '';
Begin
dbms_output.put_line('****'||Dept_Name);
select EMP_NAME INTO EMP_NAME_var
from(
select EMP_NAME,rank() over(order by salary desc) rn from employee 
where DEPT_CD=(select DEPT_CD from DEPARTMENT where DEPT_NAME=Dept_Name)) a where rn=1;
/*RETURN EMP_NAME_var;*/
END;

当我运行这个我得到这个错误:

Connecting to the database LOCAL_DEV_DB.
ORA-01427: single-row subquery returns more than one row
ORA-06512: at "LOCAL_DEV_DB.HIGH_SALARY", line 7
ORA-06512: at line 6
****'Technology'
Process exited.
Disconnecting from the database LOCAL_DEV_DB.

但是,当我单独运行子查询时,它只会按预期得到一行:

select EMP_NAME 
from(
select EMP_NAME,rank() over(order by salary desc) rn from employee 
where DEPT_CD=(select DEPT_CD from DEPARTMENT where DEPT_NAME='Technology')) a where rn=1;

结果

有人可以指出我在这里缺少什么。

标签: plsql

解决方案


我会将您的逻辑表达为两个表之间的连接。然后,用于ROW_NUMBER标识与最高薪水员工对应的给定部门的记录。

create or replace procedure High_salary (Dept_Name IN varchar2)
AS
    EMP_NAME_var varchar2(100) := '';
    Begin dbms_output.put_line('****'||Dept_Name);
    select EMP_NAME INTO EMP_NAME_var
    from
    (
        select e.EMP_NAME, ROW_NUMBER() OVER (ORDER BY e.SALARY DESC) rn
        FROM employee e
        INNER JOIN department d
            ON e.DEPT_CD = d.DEPT_CD
        WHERE d.DEPT_NAME = Dept_Name
    ) t
    where rn = 1

END;

您当前方法的问题不一定是WHERE应该起作用的子句,而是您正在使用该RANK函数。 RANK如果两个或更多员工的最高薪水并列,则返回 1。

通过使用ROW_NUMBER,您可以确保子查询只会返回一行。


推荐阅读