DROP TABLE test /
CREATE table test ( id NUMBER ,flag VARCHAR2(1) NOT NULL ,sid NUMBER ,fetch_loop NUMBER ) /
INSERT INTO test ( id ,flag ,sid ,fetch_loop ) VALUES ( 1 ,'N' ,NULL ,NULL ) /
INSERT INTO test ( id ,flag ,sid ,fetch_loop ) VALUES ( 2 ,'N' ,NULL ,NULL ) /
INSERT INTO test ( id ,flag ,sid ,fetch_loop ) VALUES ( 3 ,'N' ,NULL ,NULL ) /
INSERT INTO test ( id ,flag ,sid ,fetch_loop ) VALUES ( 4 ,'N' ,NULL ,NULL ) /
INSERT INTO test ( id ,flag ,sid ,fetch_loop ) VALUES ( 5 ,'N' ,NULL ,NULL ) /
INSERT INTO test ( id ,flag ,sid ,fetch_loop ) VALUES ( 6 ,'N' ,NULL ,NULL ) /
INSERT INTO test ( id ,flag ,sid ,fetch_loop ) VALUES ( 7 ,'Y' ,NULL ,NULL ) /
INSERT INTO test ( id ,flag ,sid ,fetch_loop ) VALUES ( 8 ,'Y' ,NULL ,NULL ) /
COMMIT /
SELECT * FROM test ORDER BY id /
PROMPT Run test_script_b.sql in another session now.
DECLARE TYPE id_type IS TABLE OF test.id%TYPE INDEX BY BINARY_INTEGER;
l_sid NUMBER; l_fetch_loop NUMBER := 0; l_limit NUMBER := 3;
id_tab id_type;
CURSOR r_ids IS SELECT id FROM test WHERE flag = 'N' FOR UPDATE;
BEGIN SELECT sid INTO l_sid FROM v$session WHERE audsid = SYS_CONTEXT('userenv', 'sessionid');
OPEN r_ids;
dbms_lock.sleep(5);
LOOP l_fetch_loop := l_fetch_loop + 1;
FETCH r_ids BULK COLLECT INTO id_tab LIMIT l_limit;
FORALL l_i IN id_tab.FIRST .. id_tab.LAST UPDATE test SET flag = 'Y' ,sid = l_sid ,fetch_loop = l_fetch_loop WHERE id = id_tab(l_i);
EXIT WHEN r_ids%NOTFOUND; END LOOP;
COMMIT;
CLOSE r_ids; END; /
|