sql >> データベース >  >> RDS >> Oracle

Oracleは更新動作を選択します

    FOR UPDATE SKIP LOCKEDで発生した動作は、このブログノートで説明されています。私の理解では、FORUPDATE句はWHERE句の後に評価されます。 SKIP LOCKEDは、返されるはずの行のうち、ロックされていない行がないことを保証する追加のフィルターのようなものです。

    あなたのステートメントは論理的に次のようになります:card_numbersから最初の行を見つける ロックされていない場合は返却してください。明らかに、これはあなたが望むものではありません。

    説明した動作を再現する小さなテストケースを次に示します。

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

    2番目の選択から行は返されません。カーソルを使用してこの問題を回避できます:

    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
    

    カーソルを明示的にフェッチしたので、1行だけが返されます(1行だけがロックされます)。



    1. SQLケース:3つのあまり知られていない面倒を知って回避する

    2. Postgresqlでキャリッジリターンと新しい行を削除するにはどうすればよいですか?

    3. MySQLでのWEIGHT_STRING()関数のしくみ

    4. CTEと誕生日のパラドックス