1.FOR UPDATE
为了对正在处理的行不被另外的用户改动,Oracle提供了FOR UPDATE
关键字来对所选择的行锁住。
在游标中,若创建的游标需要执行更新或删除的必须带有
FOR UPDATE
关键字,不然会报错。
FOR UPDATE
关键字会将查询出来的数据进行行级锁定,这样在本会话期间,其他用户的会话就无法改变那些数据。
- 用户对某表进行上锁
<SELECT_statement> FOR UPDATE;
- 在锁表的用户提交事务之前,其他用户不能对该表进行update和delete操作
2.FOR UPDATE NOWAIT
在执行SELECT语句时发现要操作的数据记录已经被锁定,则直接返回,不等待。
<SELECT_statement> FOR UPDATE NOWAIT;
3.WHERE CURRENT OF
使用该字句,则需要在定义游标的时候加上FOR UPDATE
子句,不然会报错。
WHERE CURRENT OF <cursor_name>
的含义是定位最近一次进行fetch <cursor_name>
操作 获取的记录,这样在进行update
或者是delete
的时候就不用使用where
去定位到具体的记录。
用法如下:
update
UPDATE <table_name>
SET <set_clause>
WHERE CURRENT OF <cursor_name>;
delete
DELETE FROM <table_name>
WHERE CURRENT OF <cursor_name;>
- 具体示例
用例为oracle创建时scott用户自带的表
CREATE TABLE emp01
AS
SELECT * FROM scott.emp;
- 删除记录。删除工资小于n的员工
DECLARE
rec emp01%ROWTYPE;
CURSOR c_del_emp
IS
SELECT * FROM emp01 WHERE sal <&n FOR UPDATE NOWAIT ;
# &n表示接收从键盘输入的数据
BEGIN
OPEN c_del_emp;
LOOP
FETCH c_del_emp INTO rec;
EXIT WHEN c_del_emp%NOTFOUND;
DELETE FROM emp01 WHERE CURRENT OF c_del_emp;
dbms_output.put_line(rec.ename);
END LOOP;
END;
- 更新记录。更新工资小于n的员工为2000
DECLARE
rec emp01%ROWTYPE;
CURSOR c_upd_emp
IS
SELECT * FROM emp01 WHERE sal <&n FOR UPDATE NOWAIT ;
# &n表示接收从键盘输入的数据
BEGIN
OPEN c_upd_emp;
LOOP
FETCH c_upd_emp INTO rec;
EXIT WHEN c_upd_emp%NOTFOUND;
dbms_output.put_line(rec.ename||rec.sal);
UPDATE emp01 SET sal=2000 WHERE CURRENT OF c_upd_emp;
END LOOP;
END;
4.OF子句
OF
子句需要搭配FOR UPDATE
使用。
- 当
SELECT
语句中涉及到多张表时,平常使用FOR UPDATE
不加OF
表示将涉及到的表的有关记录锁住。 - 使用
FOR UPDATE OF <table_name>
可以只锁住指定的表的记录。
参考资料:https://blog.csdn.net/qq_33404395/article/details/79918742
参考资料:https://blog.csdn.net/yoursly/article/details/79331750
参考资料:https://blog.csdn.net/kb5706/article/details/7577431
参考资料:https://zheng12tian.iteye.com/blog/815770
原文:blog.isdevil.com