sql >> Database teknologi >  >> RDS >> Oracle

Oracle vælg til opdateringsadfærd

Den adfærd, du er stødt på for FOR OPDATERING SKIP OVER LÅST, er blevet beskrevet i denne blognote. Min forståelse er, at FOR UPDATE-klausulen evalueres EFTER WHERE-klausulen. SKIP LOCKED er som et ekstra filter, der garanterer, at ingen blandt de rækker, der ville være blevet returneret, er låst.

Dit udsagn svarer logisk til:find den første række fra card_numbers og returner den, hvis den ikke er låst. Det er åbenbart ikke, hvad du ønsker.

Her er en lille testcase, der gengiver den adfærd, du beskriver:

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

Ingen række returneres fra det andet valg. Du kan bruge en markør til at omgå dette problem:

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

Da jeg eksplicit har hentet markøren, vil kun én række blive returneret (og kun én række vil blive låst).



  1. Lær, hvordan du bruger CASE-sætning i SQL

  2. Hvordan springer man over kolonner i CSV-fil, når man importerer til MySQL-tabel ved hjælp af LOAD DATA INFILE?

  3. Opstart af RAC-database mislykkes med fejl ORA-12547

  4. Sådan ændres Datetime-formater i MySQL