PL/SQL中使用Cursor修改表:新增列及薪资更新问题咨询
用PL/SQL游标处理表修改及添加新列的方案
我来帮你一步步搞定这个需求,先理清楚逻辑:首先得给现有表加新列,然后用游标完成薪资更新的操作,最后再总结PL/SQL里用游标改表的核心方法。
第一步:先给表添加new_sal新列
首先要明确,添加列是DDL操作,完全不需要游标,直接用ALTER TABLE语句就能搞定。假设你的员工表叫employees,执行下面的语句就行:
ALTER TABLE employees ADD new_sal NUMBER(8,2);
这一步必须先做,不然后面没地方存更新后的薪资数据。
第二步:用游标实现部门20员工薪资更新并存入新列
接下来用PL/SQL游标来处理具体的更新逻辑,这里给你两种常用的实现方式,你可以根据场景选:
方式1:显式游标(适合需要精细控制的场景)
显式游标需要手动打开、读取、关闭,适合要处理异常或者逐行做复杂判断的情况:
DECLARE -- 声明游标,只筛选部门20的员工,加上FOR UPDATE锁定行防止并发冲突 CURSOR emp_cursor IS SELECT employee_id, salary FROM employees WHERE department_id = 20 FOR UPDATE; -- 定义变量存储游标读取的数据,用%TYPE匹配表字段类型,更灵活 v_emp_id employees.employee_id%TYPE; v_old_sal employees.salary%TYPE; BEGIN OPEN emp_cursor; -- 打开游标 LOOP FETCH emp_cursor INTO v_emp_id, v_old_sal; -- 把游标当前行的数据读到变量里 EXIT WHEN emp_cursor%NOTFOUND; -- 当游标没数据了就退出循环 -- 计算涨5%后的薪资,更新new_sal列 UPDATE employees SET new_sal = v_old_sal * 1.05 WHERE CURRENT OF emp_cursor; -- 用CURRENT OF直接定位游标当前行,不用再写employee_id条件 END LOOP; CLOSE emp_cursor; -- 关闭游标 COMMIT; -- 提交事务,确保修改生效 DBMS_OUTPUT.PUT_LINE('部门20员工的新薪资已经成功存入new_sal列啦'); EXCEPTION WHEN OTHERS THEN ROLLBACK; -- 出错就回滚,避免脏数据 DBMS_OUTPUT.PUT_LINE('更新失败了:' || SQLERRM); -- 输出错误信息 END; /
方式2:隐式FOR循环游标(更简洁,日常开发推荐)
PL/SQL的隐式游标FOR循环会自动帮你处理打开、读取、关闭游标这一系列操作,代码更简洁,写起来更省心:
BEGIN -- 直接用FOR循环遍历游标结果,emp_rec是自动生成的记录变量,存储每一行的数据 FOR emp_rec IN ( SELECT employee_id, salary FROM employees WHERE department_id = 20 FOR UPDATE ) LOOP -- 直接用emp_rec里的salary计算新薪资,更新new_sal列 UPDATE employees SET new_sal = emp_rec.salary * 1.05 WHERE CURRENT OF emp_rec; -- 定位到当前循环的行 END LOOP; COMMIT; DBMS_OUTPUT.PUT_LINE('部门20员工的薪资更新完成,新数据已经存在new_sal列中'); EXCEPTION WHEN OTHERS THEN ROLLBACK; DBMS_OUTPUT.PUT_LINE('操作出错了:' || SQLERRM); END; /
PL/SQL中用游标修改表的核心注意事项
FOR UPDATE子句:一定要加在游标查询里,它会锁定你要修改的行,防止在你操作的时候其他会话修改这些数据,避免并发冲突。如果不想等太久,可以加WAIT 5(等待5秒超时)或者NOWAIT(立即报错),比如FOR UPDATE WAIT 5。CURRENT OF子句:这个是关键,它能直接定位到游标当前指向的行,不用再写WHERE条件去匹配主键,既省事又能避免因为主键重复或者写错条件导致的错误。- 事务处理:修改完必须
COMMIT提交,出错了要ROLLBACK回滚,保证数据的一致性,不然你的修改只是在当前会话有效,关闭会话就没了。 - 如果要同时更新原薪资列:要是你不仅想把新薪资存在
new_sal,还想更新原来的salary列,只需要在UPDATE语句里加上salary = emp_rec.salary * 1.05就行,比如:UPDATE employees SET salary = emp_rec.salary * 1.05, new_sal = emp_rec.salary * 1.05 WHERE CURRENT OF emp_rec;
内容的提问来源于stack exchange,提问作者Soutrik Mukherjee
相关产品推荐
相关产品推荐

