子查询在PL / SQL存储过程中返回多个行

时间:2019-02-20 08:36:49

标签: plsql

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

下面是我的桌子的屏幕截图:

Department tables

Employee table

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

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;

Result

有人可以指出我在这里想念的东西吗。

3 个答案:

答案 0 :(得分:1)

我将您的逻辑表示为两个表之间的联接。然后,使用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,您可以确保子查询仅返回单行。

答案 1 :(得分:1)

问题很可能来自您的变量名与字段名相同的事实。在该过程中,它将Dept_Name与自身进行比较,并且毫无疑问,所有行都匹配。

在此过程中,尝试命名变量DeptNameVar或类似名称,更新查询中的引用,看看是否有帮助。

答案 2 :(得分:0)

由于语句的这一部分,您遇到了该错误 选择EMP_NAME,从员工那里按等级排序(按薪水顺序排序)。 您正在拉两列,一列是EMP_NAME,另一列是rank()over(按薪水高低排序)rn。这就是为什么您会收到该错误的原因。 请修改子查询,以便仅选择emp_name。