Oracle PL/SQL选择和更新

atr*_*nce 1 sql oracle plsql oracle10g

当我执行这个PL/SQL块时,我一直收到"没有找到数据".如果我注释掉输出行,那么一切都按照我的怀疑输出,但更新语句永远不会执行.有任何想法吗?

set serveroutput on;
Declare
   TYPE type_emp IS RECORD(
        emp_salary emp.salary%TYPE);
     rec_emp type_emp;
   v_stars varchar2(50) ;
   v_count number(3);
   s_num number(3);
begin
 SELECT min(employee_id) into s_num from emp;
 SELECT count(*) into v_count from emp;
 v_count := v_count + s_num;
 for i in s_num .. v_count loop
   SELECT salary
     into rec_emp
     from emp
    where employee_id = i; 
    if rec_emp.emp_salary <1000 then 
        v_stars := null;
      elsif rec_emp.emp_salary >=1000 and rec_emp.emp_salary <2000 then 
        v_stars := '*';
      elsif rec_emp.emp_salary >=2000 and rec_emp.emp_salary <3000 then 
        v_stars := '**';
      elsif rec_emp.emp_salary >=3000 and rec_emp.emp_salary <4000 then 
        v_stars := '***';
      elsif rec_emp.emp_salary >=4000 and rec_emp.emp_salary <5000 then 
        v_stars := '****';
      elsif rec_emp.emp_salary >=5000 and rec_emp.emp_salary <6000 then 
        v_stars := '*****';
      elsif rec_emp.emp_salary >=6000 and rec_emp.emp_salary <7000 then 
        v_stars := '******';
      elsif rec_emp.emp_salary >=7000 and rec_emp.emp_salary <8000 then 
        v_stars := '*******';
      elsif rec_emp.emp_salary >=8000 and rec_emp.emp_salary <9000 then
        v_stars := '********';
      elsif rec_emp.emp_salary >=9000 and rec_emp.emp_salary <10000 then 
        v_stars := '*********';
      elsif rec_emp.emp_salary >=10000 and rec_emp.emp_salary <11000 then 
        v_stars := '**********';
      elsif rec_emp.emp_salary >=11000 and rec_emp.emp_salary <12000 then 
        v_stars := '***********';
      elsif rec_emp.emp_salary >=12000  then 
        v_stars := '************';
    end if;
    --dbms_output.put_line(rec_emp.emp_salary || '   ' || i || '      '|| v_stars);  
    update emp set emp.stars = v_stars where employee_id = i;
 end loop;
 end;
Run Code Online (Sandbox Code Playgroud)

Jef*_*emp 8

您正在使用一种非常不寻常的方法来遍历表中的所有记录.您的方法假定员工ID是连续的(即没有间隙).它还有一个错误的错误.

假设您的表格包含以下行:

100
101
102
103
104
Run Code Online (Sandbox Code Playgroud)

首先,您获得最低员工ID : s_num = 100.

然后,你得到记录的数量:v_count = 5.

最后,将这些添加到一起以获得上限: s_num + v_count = 105

你现在能看到你的循环问题吗?在最后一次迭代中,您的查询:

SELECT salary
 into rec_emp
 from emp
where employee_id = i; 
Run Code Online (Sandbox Code Playgroud)

将寻找提升的员工ID 105 NO_DATA_FOUND.DBMS_OUTPUT调用已经完成,所以你会看到输出; 但是未处理的异常会导致回滚,这意味着您的UPDATE将被撤消.

相反,你可以使你的循环更简单,例如:

FOR rec_emp IN (SELECT employee_id, salary AS emp_salary FROM emp) LOOP
  if rec_emp.emp_salary <1000 then 
    v_stars := null;
  elsif <snip>
    ...
  end if;
  --dbms_output.put_line(rec_emp.emp_salary || '   ' || i || '      '|| v_stars);  
  update emp set emp.stars = v_stars where employee_id = i;
END LOOP;
Run Code Online (Sandbox Code Playgroud)

上面的代码也稍微有点效率.它可以变得更有效率,但我不希望这个答案远远超过你迄今为止的目标.

我希望这有帮助.