oracle PlSql陷入无限循环

eanckbw9  于 2023-04-29  发布在  Oracle
关注(0)|答案(2)|浏览(135)

我有一个有7列的表,其中包含以下员工信息,但行数要多得多,随着新员工的到来,我会添加更多。
| emp_number|薪金|部门编号|等等|等等|等等|等等|
| --------------|--------------|--------------|--------------|--------------|--------------|--------------|
| 0001|11111|10个|二号牢房|1号牢房|二号牢房|1号牢房|
| 0002|22222|二十|二号牢房|1号牢房|二号牢房|1号牢房|
| 0003|333333|三十|二号牢房|1号牢房|二号牢房|1号牢房|
| 0004|四四四四四|10个|二号牢房|1号牢房|二号牢房|1号牢房|
我试图编码一个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;
x9ybnkn6

x9ybnkn61#

如果你用缩进来格式化你的代码,你会有更好的成功。以下是我添加意图后的结果:

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;

在主光标LOOP中有多个内部LOOP,您正在获取内部循环。每个外部游标LOOP只在末尾取一次。你也有一个没有明确退出条件的循环:

while depcursor<depcompare loop
  fetch cur1 into empleadus;

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

这是进入无限循环的简单方法。你不能确定dept_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
hlswsv35

hlswsv352#

您可以使用公共表表达式。不需要游标。下面的查询将从每个部门中选择两个薪资最低的员工。

with minEmpSalary as
(select emp_numb,salary,dept_num,etc,row_number()over(partition by dept_num order by salary)rn from employees 
)
select emp_numb,salary,dept_num,etc from minEmpSalary where rn<=2

相关问题