sql >> Databáze >  >> RDS >> Oracle

Oracle vybrat chování aktualizace

Chování, se kterým jste se setkali pro FOR UPDATE SKIP LOCKED, bylo popsáno v této poznámce k blogu. Chápu to tak, že klauzule FOR UPDATE se vyhodnocuje PO klauzuli WHERE. SKIP LOCKED je jako další filtr, který zaručuje, že mezi řádky, které by byly vráceny, není žádný uzamčen.

Váš výpis je logicky ekvivalentní:najděte první řádek z card_numbers a vraťte jej, pokud není uzamčen. Očividně to není to, co chcete.

Zde je malý testovací případ, který reprodukuje chování, které popisujete:

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

Z druhého výběru není vrácen žádný řádek. Tento problém můžete vyřešit pomocí kurzoru:

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

Protože jsem explicitně načetl kurzor, bude vrácen pouze jeden řádek (a pouze jeden řádek bude uzamčen).



  1. SQLite JSON_VALID()

  2. Intel SSD, nyní mimo seznam hanebných

  3. Funkce pro odstranění akcentů v postgreSQL

  4. Nejbližší zápas, část 3