1、加锁会锁住游标中的所有数据行,而不是只锁定取出的数据行
DECLARE
CURSOR c1 IS
SELECT empno, job, sal
FROM emp
FOR UPDATE;
...
BEGIN
OPEN c1;
LOOP
FETCH c1
INTO ...
...
UPDATE emp
SET sal = new_sal
WHERE CURRENT OF c1;
END LOOP;
END;
2、加锁的游标,打开后,如果提交事务的话,就再无法取出数据了。
eg:FOR UPDATE子句能获取排他锁。打开游标时所有的行都会被锁住,在事务提交后锁会被释放。所以,我们不能在事务提交后从使用了FOR UPDATE子句的游标中取得数据。如果这样做的话,PL/SQL就会抛出异常。下例中,游标FOR循环在第十次插入操作后会执行失败
DECLARE
CURSOR c1 IS
SELECT ename
FROM emp
FOR UPDATE OF sal;
ctr NUMBER := 0;
BEGIN
FOR emp_rec IN c1 LOOP -- FETCHes implicitly
...
ctr := ctr + 1;
INSERT INTO temp
VALUES (ctr, 'still going');
IF ctr >= 10 THEN
COMMIT; -- releases locks
END IF;
END LOOP;
END;
如果想在数据提交后也能取得数据,就不要使用FOR UPDATE和CURRENT OF子句。我们可以使用伪列ROWID模拟CURRENT OF子句。只要把每行的ROWID放到UROWID类型的变量中就可以了。然后在后续的更新和删除操作中用ROWID来辨识当前行。