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

Posted

技术标签:

【中文标题】PLSQL新工资不显示或显示错误【英文标题】:PLSQL new salary is not displaying or displaying wrong 【发布时间】:2011-12-15 19:27:07 【问题描述】:

谢谢你的想法

我必须编写一个计算项目数量的程序,并且 员工 ID 作为传递的员工的平均工作时间 过程的参数。如果平均工作时间少于 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】:

变量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;
/

【讨论】:

我是 plsql 的新手,如果不创建新光标,我怎么能做到这一点 我已经修复了一些错误。我还添加了代码来显示新旧工资。现在它应该做你想做的事

以上是关于PLSQL新工资不显示或显示错误的主要内容,如果未能解决你的问题,请参考以下文章

明智地显示员工表部门的运行工资,而不使用滞后、领先或分区

PLSQL块增加部门的工资

Oracle数据库在plsql中文乱码,显示问号????

在plsql中为null时是不是可以不显示xmlelement?

新建的数据库怎么在plsql中不显示,数据库只显示ORCL

PLSQL:在存储过程中使用动态查询时不显示输出