我有一个有7列的表,上面有关于员工的信息,如下所示,但行数要多得多,并将随着新员工的到来而添加更多.

emp_numb salary dept_num etc etc etc etc
0001 111111 10 Cell 2 Cell 1 Cell 2 Cell 1
0002 222222 20 Cell 2 Cell 1 Cell 2 Cell 1
0003 333333 30 Cell 2 Cell 1 Cell 2 Cell 1
0004 444444 10 Cell 2 Cell 1 Cell 2 Cell 1

我正在try 编写一个PLSQL程序,这样我就可以看到每个部门工资最低的2名员工(如果稍后我添加了更多的部门编号,则需要能够使用此程序). 问题是,对于我到目前为止编写的代码,我陷入了无限循环,无法理解到目前为止我在哪里失败了.如果问题不是很多,因为我是SQL的新手,而且我的知识也不是很丰富,那么有人可以判断我的代码并告诉我哪里出了问题吗?提前感谢!!

我的代码如下:

create or replace procedure lowemployees
as
cursor cur1 is select * from emple order by dept_no,salario;
empleadus emple%rowtype;
i number;
depcursor emple.dept_no%type;
depcompare emple.dept_no%type;
begin
i:=0;
open cur1;
fetch cur1 into empleadus;
depcursor:=empleadus.dept_no;
depcompare:=depcursor+1;
while cur1%found loop
while i<2 loop
dbms_output.put_line(empleadus.emp_no||'|'||empleadus.nombre||'|'||empleadus.oficio||'|'||empleadus.salario||'|'||empleadus.dept_no);
i:=i+1;
fetch cur1 into empleadus;
end loop;
depcursor:=empleadus.dept_no;
depcompare:=depcursor+1;
while depcursor<depcompare loop
fetch cur1 into empleadus;
i:=0;
depcursor:=empleadus.dept_no;
end loop;
dbms_output.put_line(empleadus.emp_no||'|'||empleadus.nombre||'|'||empleadus.oficio||'|'||empleadus.salario||'|'||empleadus.dept_no);
depcompare:=depcursor+1;
fetch cur1 into empleadus;
end loop;
close cur1;
end lowemployees;

推荐答案

如果您使用缩进设置代码的格式,您将获得更好的成功.在我添加了一些建议之后,以下是您所拥有的:

create or replace procedure lowemployees
as
  cursor cur1 is 
    select * from emple order by dept_no,salario;
  empleadus emple%rowtype;
  i number;
  depcursor emple.dept_no%type;
  depcompare emple.dept_no%type;
begin
  i:=0;
  
  open cur1;
  fetch cur1 into empleadus;
  
  depcursor:=empleadus.dept_no;
  depcompare:=depcursor+1;
  
  while cur1%found loop
    while i<2 loop
      dbms_output.put_line(empleadus.emp_no||'|'||empleadus.nombre||'|'||empleadus.oficio||'|'||empleadus.salario||'|'||empleadus.dept_no);
      i:=i+1;
      
      fetch cur1 into empleadus;
    end loop;
    
    depcursor:=empleadus.dept_no;
    depcompare:=depcursor+1;
    
    while depcursor<depcompare loop
      fetch cur1 into empleadus;
      
      i:=0;
      depcursor:=empleadus.dept_no;
    end loop;
    
    dbms_output.put_line(empleadus.emp_no||'|'||empleadus.nombre||'|'||empleadus.oficio||'|'||empleadus.salario||'|'||empleadus.dept_no);
    depcompare:=depcursor+1;
    
    fetch cur1 into empleadus;
  end loop;
  
  close cur1;
end lowemployees;

您的主光标循环中有多个内部循环,并且您正在获取内部循环.在结尾处,每个外部游标循环只提取一次.您还有一个没有明确退出条件的循环:

while depcursor<depcompare loop
  fetch cur1 into empleadus;

  i:=0;
  depcursor:=empleadus.dept_no;
end loop;

这是一种进入无限循环的简单方法.你不能确定det_no会比任何东西都要少.这是一个你无法控制的数据值.你需要使用更谨慎的退出条件.

但我也建议您重新考虑使用PL/SQL.您的需求是在普通的老式SQL中非常简单的事情.不需要过程性代码和所有这些嵌套循环:

SELECT *
  FROM (SELECT e.*,
               ROW_NUMBER() OVER (PARTITION BY dept_no ORDER BY salario) rnk
          FROM emple e)
 WHERE rnk <= 2

Sql相关问答推荐

Trino/Presto sq:仅当空值位于组中第一个非空值之后时,才用值替换空值

LAG函数通过丢弃空值返回前一行

为什么TRY_CONVERT返回一个XML验证错误而不是NULL?

根据最大值为字母数字大小写分配数值

属于(日期)范围类型及其交集的总权重​

Oracle PL/SQL:解决DBMS输出大小限制的问题

从类似JSON的字符串列创建新列

从单个表达式中的分隔字符串中取平均值

SQL查询正在工作,但返回空结果

Athena 计算从日期到当前时间戳的每月计数

计算不同模式的时间跨度

如何在 SQL Server 中解决这个复杂的窗口查询?

获取多个开始-结束时间戳集之间经过的时间

INSERT INTO 语法

将一名成员金额分配给群组内的其他成员

SQL for Smarties 类型问题:从表中 Select 记录,并对某些值进行分组

一次 Select 语句中按组累计的SQL累计数

SQL获取两个日期范围之间的计数

超过100名员工的连续行

连续日期的SQL