PLSQL新工资未显示或显示错误

时间:2011-12-15 19:27:07

标签: stored-procedures select plsql cursor

谢谢你的想法

  

我必须编写一个计算项目数量的程序,并且   员工身份证作为员工身份的员工的平均工作时间   程序的参数。如果平均工作时间小于   10然后员工的工资保持不变,否则检查是否有数字   项目的工资小于4,然后是工资的5%,否则工资的10%是   增加了工资。

     

我在plsql语句中的输出有问题,它没有显示   新工资

     

这是我的plsql程序:

create or replace procedure view_data(p_id number) is
cursor c1 
is
  select count(distinct a.projectid) as PRJ_COUNT, e.empid, e.empname, e.salary as old_sal, round(avg(a.hours),0)as AVG_HOURS
  from assignment a join employee e
  on a.empid=e.empid
  where e.empid=p_id
  group by e.empid,e.empname, e.salary;
creader c1%rowtype;  
cursor c2
is
  select empid, salary as new_sal
  from employee 
  where empid=p_id for update of salary;
rate_rec c2%rowtype;

v_new_salary number;
begin
  --open c1;
  --fetch c1 into creader;
  for creader in c1 loop

  for rate_rec in c2 loop
    if creader.avg_hours < 10 then
      update employee set salary=rate_rec.new_sal
      where empid=rate_rec.empid;

    elsif creader.prj_count<4 then
      update employee set salary=rate_rec.new_sal+rate_rec.new_sal*0.05
      where empid=rate_rec.empid;

    else
      update employee set salary=rate_rec.new_sal+rate_rec.new_sal*0.1
      where empid=rate_rec.empid;

    end if;
   select salary into v_new_salary from employee
   where empid=creader.empid;

  dbms_output.put_line('Employee ID: '||creader.empid);
  dbms_output.put_line('Employee Name: '||creader.empname);
  dbms_output.put_line('Number of projects: '||creader.prj_count);
  dbms_output.put_line('Average Working Hours: '||creader.avg_hours);
  dbms_output.put_line('Old Salary: '||rate_rec.new_sal);
  dbms_output.put_line('New Salary: '||v_new_salary);

  end loop;
 end loop;



  end view_data;
  /
     

这是输出:

Employee ID: 101
Employee Name: Marlen
Number of projects: 3
Average Working Hours: 87
Old Salary: 39206
New Salary: 41166

使用游标的解决方案:

create or replace procedure view_data(p_id number) is
cursor c1 
is
  select count(distinct a.projectid) as PRJ_COUNT, e.empid, e.empname, e.salary as old_sal, round(avg(a.hours),0)as AVG_HOURS
  from assignment a join employee e
  on a.empid=e.empid
  where e.empid=p_id
  group by e.empid,e.empname, e.salary;
creader c1%rowtype;  
cursor c2
is
  select empid, salary as new_sal
  from employee 
  where empid=p_id for update of salary;
rate_rec c2%rowtype;

v_new_salary number;
v_bonus number;
begin
  for creader in c1 loop
  for rate_rec in c2 loop
    if creader.avg_hours >= 10 then
        if creader.prj_count<4 then
           update employee set salary=salary*1.05
           where empid=rate_rec.empid
           return salary into v_new_salary;

    else
           update employee set salary=salary*1.1
           where empid=rate_rec.empid
          returning salary into v_new_salary;

       end if;
    end if;
  v_bonus:=v_new_salary-rate_rec.new_sal;

  dbms_output.put_line('Employee ID: '||creader.empid);
  dbms_output.put_line('Employee Name: '||creader.empname);
  dbms_output.put_line('Number of projects: '||creader.prj_count);
  dbms_output.put_line('Average Working Hours: '||creader.avg_hours);
  dbms_output.put_line('Old Salary: '||creader.old_sal);
  dbms_output.put_line('Bonus: '||v_bonus);
  dbms_output.put_line('New Salary: '||v_new_salary);

  end loop;
 end loop;



  end view_data;
  /

1 个答案:

答案 0 :(得分:1)

变量rate_rec在循环范围内,而不在外部。你应该将所有put_line放在循环中。

rate_rec.new_sal是旧工资。新的将在表格中更新,而不是在上一个薪水的记录中。

我建议您进行更新,然后再次选择并检查是否已修改。您还可以在更新中使用returning子句来获取新薪水。

这是一个可能的解决方案。我没有彻底检查查询。在程序结束时应该有一个commit

set serveroutput on

create or replace procedure update_data(p_id number) is
prj_count integer;
avg_hours integer;
old_salary number;
new_salary number;
begin
    select count(a.projectid), round(avg(a.hours),0), e.salary
    into prj_count, avg_hours, old_salary
    from assignment a join employee e on a.empid=e.empid
    where e.empid=p_id
    group by e.salary;

    new_salary := old_salary;

    if avg_hours >= 10 then
        if prj_count<4 then
            update employee set salary=salary+salary*0.05
            where empid=p_id
            returning salary into new_salary;
        else
            update employee set salary=salary+salary*0.1
            where empid=p_id
            returning salary into new_salary;
        end if;
    end if;
    dbms_output.put_line('Old salary: ' || old_salary);
    dbms_output.put_line('New salary: ' || new_salary);
end update_data;
/