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

SET CONSTRAINTSALLDEFERREDが期待どおりに機能しない

    DEFERRABLEのみ 制約は延期できます。

    最初に優れた代替案を提案させてください:

    1。 INSERT 順番に

    INSERTシーケンスを逆にします ステートメント 延期する必要はありません。最もシンプルで最速-可能であれば。

    2。単一のコマンド

    単一のコマンドで実行します 。それでも、延期できない制約は各コマンドの後にチェックされるため、延期する必要はありません。 およびCTEは単一コマンドの一部と見なされます:

    WITH ins1 AS (
       INSERT INTO b(j) VALUES(2)
       )
    INSERT INTO a(i) VALUES(2);
    

    その間、最初のINSERTの値を再利用できます。;特定のケースまたは複数行の挿入に対してより安全/より便利:

    WITH ins1 AS (
       INSERT INTO b(j) VALUES(3)
       RETURNING j
       )
    INSERT INTO a(i)
    SELECT j FROM ins1;
    

    しかし、遅延制約が必要です! (本当に?)

    ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
       REFERENCES a (i) MATCH SIMPLE
       ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE;  -- !!!
    

    その後、元のコードが機能します(遅延制約によりコストがかかるため、少し遅くなります)。

    db <> fiddle こちら

    関連:

    私の元の回答マニュアルを引用 :

    しかし、それは「参照アクション」、つまりON UPDATEにのみ適用されるため、誤解を招く恐れがありました。 またはON DELETE 参照されるテーブルの行に。当面のケースはそれらの1つではありません-@zer0hedgeが指摘しました 。



    1. Solr Indexing MySQLTimestampまたはDateTimeフィールド

    2. Magento-ベーステーブルまたはビューが見つかりません

    3. PL/pgSQLの指定された値のリストをループする

    4. Dockerphp_network_getaddressesエラー