Oracle
 sql >> Base de données >  >> RDS >> Oracle

Oracle sélectionner pour le comportement de mise à jour

Le comportement que vous avez rencontré pour FOR UPDATE SKIP LOCKED a été décrit dans cette note de blog. Ma compréhension est que la clause FOR UPDATE est évaluée APRÈS la clause WHERE. Le SKIP LOCKED est comme un filtre supplémentaire qui garantit que parmi les lignes qui auraient été retournées, aucune n'est verrouillée.

Votre instruction est logiquement équivalente à :trouvez la première ligne de card_numbers et retournez-le s'il n'est pas verrouillé. Évidemment, ce n'est pas ce que vous voulez.

Voici un petit cas de test qui reproduit le comportement que vous décrivez :

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
----------

Aucune ligne n'est renvoyée à partir de la deuxième sélection. Vous pouvez utiliser un curseur pour contourner ce problème :

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

Puisque j'ai explicitement récupéré le curseur, une seule ligne sera renvoyée (et une seule ligne sera verrouillée).