Het gedrag dat u bent tegengekomen voor FOR UPDATE SKIP LOCKED is beschreven in deze blognotitie. Ik heb begrepen dat de FOR UPDATE-component wordt geëvalueerd NA de WHERE-component. De SKIP LOCKED is als een extra filter dat garandeert dat van de rijen die zouden zijn geretourneerd, er geen zijn vergrendeld.
Uw verklaring is logisch gelijk aan:zoek de eerste rij van card_numbers
en stuur het terug als het niet is vergrendeld. Dit is duidelijk niet wat je wilt.
Hier is een kleine testcase die het gedrag reproduceert dat u beschrijft:
SQL> CREATE TABLE t (ID PRIMARY KEY)
2 AS SELECT ROWNUM FROM dual CONNECT BY LEVEL <= 1000;
Table created
SESSION1> select id from t where rownum <= 1 for update skip locked;
ID
----------
1
SESSION2> select id from t where rownum <= 1 for update skip locked;
ID
----------
Er wordt geen rij geretourneerd van de tweede selectie. U kunt een cursor gebruiken om dit probleem te omzeilen:
SQL> CREATE FUNCTION get_and_lock RETURN NUMBER IS
2 CURSOR c IS SELECT ID FROM t FOR UPDATE SKIP LOCKED;
3 l_id NUMBER;
4 BEGIN
5 OPEN c;
6 FETCH c INTO l_id;
7 CLOSE c;
8 RETURN l_id;
9 END;
10 /
Function created
SESSION1> variable x number;
SESSION1> exec :x := get_and_lock;
PL/SQL procedure successfully completed
x
---------
1
SESSION2> variable x number;
SESSION2> exec :x := get_and_lock;
PL/SQL procedure successfully completed
x
---------
2
Aangezien ik de cursor expliciet heb opgehaald, wordt er slechts één rij geretourneerd (en wordt slechts één rij vergrendeld).