【问题标题】:PLSQL block to increase salary of departmentsPLSQL块增加部门的工资
【发布时间】:2020-08-02 04:32:18
【问题描述】:

我必须将在 deptno 10 工作的员工的薪水增加 15%,Deptno 20 增加 15%,其他人增加 5%,并显示在该部门工作的相应员工。我能够增加部门 10 的薪水和 20 但我无法将其他部门的工资提高 5%。我也尝试过for循环。这是一个练习题。

我的问题是这样的:(显示 Dept 表中的所有记录。将在 deptno 10 工作的员工的薪水增加 15%,Deptno 20 增加 15%,其他人增加 5% 还显示相应的员工在那个部门工作。使用参数 Cursor 和 Cursor with Update 子句。)

我的代码:

declare 
cursor sal_increase(v_dno number) is select empno,sal,ename,deptno from emp where deptno=v_dno ;
emp_record sal_increase%rowtype;
begin
OPEN sal_increase(10);
LOOP
FETCH sal_increase INTO emp_record;
EXIT WHEN sal_increase%NOTFOUND;
update emp set sal=sal+sal*0.15 where empno=emp_record.empno;
DBMS_OUTPUT.PUT_LINE(emp_record.ename||' '||emp_record.deptno);
END LOOP;
CLOSE sal_increase;
OPEN sal_increase(20);
LOOP
FETCH sal_increase INTO emp_record;
EXIT WHEN sal_increase%NOTFOUND;
update emp set sal=sal+sal*0.15 where empno=emp_record.empno;
DBMS_OUTPUT.PUT_LINE(emp_record.ename||' '||emp_record.deptno);
END LOOP;
CLOSE sal_increase;
end;

【问题讨论】:

  • 这必须在 PL/SQL 中完成吗?我可以用纯 SQL 来做吗?
  • 是的,它被指定使用 pl/sql 执行此操作。

标签: sql oracle plsql


【解决方案1】:

您根本不需要任何程序代码来执行此操作。这只会不必要地严重减慢速度,尤其是使用光标。

而只是使用简单的UPDATECASE 表达式返回取决于部门的新工资。

UPDATE emp
       SET sal = CASE
                   WHEN deptno IN (10, 20) THEN
                     sal * 0.15
                   ELSE
                     sal * 0.05
                 END;

对于输出,只需使用 SELECT

SELECT ename || ' ' || deptno
       FROM emp;

【讨论】:

  • 我必须用 PL/SQL 来回答这个问题。
  • 如果您必须在 PL/SQL 中执行此操作,只需将简单的更新语句包装在 BEGIN .. END 中即可。瞧!您现在拥有 PL/SQL。
【解决方案2】:

不要忘记来自 @sticky bit 的解决方案以备不时之需。

回到你的要求,我相信你坚持用一个匿名块和参数化光标来做。(如果我错了,请纠正我)

如果是,我会更改以下内容,它应该为您完成工作。

将光标更改为下方,对于其他人,您将 null 作为参数传递,在 where 子句中我们可以处理相同的问题。 (当值传递为 10 或 20 时,它将进行比较,当为 null 时,它将更新 10 和 20 以外的所有值)

CURSOR sal_increase(v_dno NUMBER) IS
      SELECT empno
            ,sal
            ,ename
            ,deptno
      FROM   emp
      WHERE  (   v_dno IS NOT NULL AND deptno = v_dno 
              OR v_dno IS NULL AND deptno NOT IN (10,20)
              );

然后像下面一样再次调用 10 和 20 的 cusrosr,

   OPEN sal_increase(v_dno => NULL);
   LOOP
      FETCH sal_increase
         INTO emp_record;
      EXIT WHEN sal_increase%NOTFOUND;
      UPDATE emp SET sal = sal * 0.05 WHERE empno = emp_record.empno;
      dbms_output.put_line(emp_record.ename || ' ' || emp_record.deptno);
   END LOOP;
   CLOSE sal_increase;

【讨论】:

  • 我更新后你能看到我的问题吗?你提供的这个解决方案对我有用。
  • @mayank:当我看到您更新的问题时,要求还显示“带有更新子句的光标”。我不确定这个更新子句是否引用了开始端的更新语句或类似techonthenet.com/oracle/cursors/current_of.php.... 因为当两个并发用户更新相同的记录时,我们实际上可以使用带有更新子句的游标来处理锁定。有关详细信息,请参阅我提供的链接。
猜你喜欢
  • 2021-10-16
  • 2023-03-22
  • 2013-05-23
  • 2019-01-25
  • 2022-11-10
  • 2021-09-09
  • 1970-01-01
  • 2016-07-07
  • 2016-06-20
相关资源
最近更新 更多