我的脚本需要执行以下操作
如果部门是10,工资高于2000给予6%的加薪,否则给7%的加薪。2如果部门是20,工资高于2500,给5%的加薪,否则给5.5%的加薪。
但是程序并没有运行完我所有的if语句,它停在了第一个if语句上,我不确定我还能用什么其他逻辑让它运行完所有的if语句。
SET SERVEROUTPUT ON
DECLARE
v_newsal emp.sal%TYPE;
v_sal emp.sal%TYPE;
v_deptno emp.deptno%TYPE;
CURSOR raise_cursor IS
SELECT sal, deptno
FROM emp;
BEGIN
OPEN raise_cursor;
fetch raise_cursor INTO v_sal, v_deptno;
LOOP
IF v_deptno = 10 AND v_sal > 2000 THEN
v_newsal := v_sal * 1.060;
ELSE
v_newsal := v_sal * 1.070;
IF v_deptno = 20 AND v_sal > 2500 THEN
v_newsal := v_sal * 1.050;
ELSE
v_newsal := v_sal * 1.055;
END IF;
END IF;
UPDATE emp SET
sal = v_newsal
WHERE deptno = v_deptno;
EXIT;
END LOOP;
CLOSE raise_cursor;
END;
/
SET SERVEROUTPUT OFF
我试过elsif语句和嵌套的if语句,只是常规的if else语句,但似乎都不起作用。
4条答案
按热度按时间px9o7tmv1#
问题是您要打开游标,读取一行,然后启动一个循环,在第一个循环结束时退出。
处理此类游标的常用方法是:打开游标,开始循环,读取行,如果找不到行则退出循环,如果找到行则继续执行其余的逻辑,然后返回到循环的开头并重复。
我假设您的过程是处理游标的学习练习的一部分,因为在真实的生活中,您最好像@Littlefoot在他们的回答中建议的那样,在单个update语句中处理逻辑。
在此基础上,您的代码应该如下所示:
注意:游标for循环(
for <record> in <cursor> loop <logic> end loop;
)编写起来更简单、更清晰,而且还具有内置优化功能,可以将逐行处理转换为批量行处理。它为您处理游标的打开、获取和退出,因此您无需担心它。然而,正如我所说的,我假设您正在学习如何显式地处理游标周围的打开、循环等操作。另外,看看if语句的逻辑,它也没有意义:
如果部门是10,工资高于2000给予6%的加薪,否则给7%的加薪。2如果部门是20,工资高于2500,给5%的加薪,否则给5.5%的加薪。
第一个“else”子句只与第10部门有关吗?与第20部门也一样吗?您当前的逻辑意味着,如果您在第20部门的工资低于2500美元,或者在任何其他部门,您将从第一个查询中获得6%的加薪,然后在此基础上获得5.5%的加薪(对员工来说是甜蜜的交易,对雇主来说不是那么多!)
如果我对逻辑的理解是正确的,它应该是这样的:
;
fslejnso2#
您可以使用单个
UPDATE
语句,使用WHERE
子句仅更新特定部门中的员工,使用CASE
表达式将不同的部门/薪金范围Map到加薪百分比:qv7cva1a3#
也许是这样的
dgiusagp4#
实际上,您不需要在循环中进行低效的逐行处理;将单个
update
语句与case
表达式一起使用: