问题: 编写一个PL / SQL块,根据以下标准为每个员工提供加薪: 保存为q3.sql不需要测试脚本。 •低于1000的员工获得6%的加薪 •1000至3000人的员工人数增加8% •员工人数超过3000人的人数增加12% 每次加注时,使用dbms_output打印消息“,你刚刚获得n%加薪,你的新工资是”。当所有加注完成后,回滚交易并打印消息,“他,他,他......开个玩笑!”
它执行正确的计算并返回没有错误,尽管它在前一个记录上进行计算然后跳过下一个记录。
SET SERVEROUTPUT ON
DECLARE
CURSOR sal_cursor IS
SELECT ename, sal
FROM EMP
FOR UPDATE OF sal NOWAIT;
V_sal emp.sal%TYPE;
V_ENAME EMP.Ename%TYPE;
BEGIN
FOR emp_record IN sal_cursor
LOOP
FETCH sal_cursor INTO V_Ename, V_Sal;
IF (V_SAL <= 1000) THEN
UPDATE emp
SET EMP.sal = (emp_record.sal * 1.06)
WHERE CURRENT OF sal_cursor;
v_sal := v_sal * 1.06;
ELSIF V_SAL > 1000 AND V_sal <= 3000 THEN
UPDATE emp
SET EMP.sal = (emp_record.sal * 1.08)
WHERE CURRENT OF sal_cursor;
v_sal := v_sal * 1.08;
ELSE
UPDATE emp
SET EMP.sal = (emp_record.sal * 1.12)
WHERE CURRENT OF sal_cursor;
v_sal := v_sal * 1.12;
END IF;
DBMS_OUTPUT.PUT_LINE(V_ENAME || ', you just got an n percent raise
and your new salary is ' || v_sal);
END LOOP;
DBMS_OUTPUT.PUT_LINE('He, he, he... just kidding!');
ROLLBACK;
END;
答案 0 :(得分:0)
FOR语句已从光标中提取记录。所以不要在以下行中执行FETCH。
答案 1 :(得分:0)
您正在混淆two ways of handling cursors - 显式和隐式CURSOR FOR
循环。您可以比较从该语法页面链接的示例。
FOR emp_record IN sal_cursor
方法会自动将每一行提取到emp_record
变量中。然后,您明确的FETCH
会读取 next 记录。 (我有点惊讶它并没有抱怨它。)
SET SERVEROUTPUT ON
DECLARE
CURSOR sal_cursor IS
SELECT ename, sal
FROM EMP
FOR UPDATE OF sal NOWAIT;
V_sal emp.sal%TYPE;
BEGIN
FOR emp_record IN sal_cursor
LOOP
IF (emp_record.sal <= 1000) THEN
v_sal := emp_record.sal * 1.06;
ELSIF emp_record.sal > 1000 AND emp_record.sal <= 3000 THEN
v_sal := emp_record.sal * 1.08;
ELSE
v_sal := emp_record.sal * 1.12;
END IF;
UPDATE emp
SET EMP.sal = v_sal
WHERE CURRENT OF sal_cursor;
DBMS_OUTPUT.PUT_LINE(emp_record.ename || ', you just got an n percent raise
and your new salary is ' || v_sal);
END LOOP;
DBMS_OUTPUT.PUT_LINE('He, he, he... just kidding!');
ROLLBACK;
END;
您还可以使用CASE
语句来分配新值;或使用三个单独的UPDATE
语句和RETURNING
子句来填充v_sal
,但不知道您是否已经了解这些语句。
如果要在PL / SQL块中转到ROLLBACK
,如果遇到错误,则应该有一个异常处理程序和回滚。