一連の遅延制約によって相互に依存している 2 つのテーブルから行を削除したいと考えています。この投稿を簡単にするために、単純な DB スキーマをモックアップしました。
SQL トランザクション/DB パッチ内のテーブル 'delete_from_me' からエントリを削除したいと考えています。キャッチは、リンク自体を失う前に、2番目のテーブル「constraining_table」からの選択に基づいて削除したいということです。
2 つのテーブルの説明は次のとおりです。
tab-quarantine=> \d delete_from_me
Table "public.delete_from_me"
Column | Type | Modifiers
-----------+-------------------+-----------
id | character varying | not null
extension | character varying | not null
Indexes:
"delete_from_me_pkey" PRIMARY KEY, btree (id)
tab-quarantine=> \d constraining_table
Table "public.constraining_table"
Column | Type | Modifiers
--------+-------------------+-----------
image | character varying | not null
type | character varying | not null
Foreign-key constraints:
"constraining_table_image_fkey" FOREIGN KEY (image) REFERENCES delete_from_me(id)
ON UPDATE CASCADE
ON DELETE RESTRICT DEFERRABLE
これは、私がそこに吹き込んだばかりのサンプルデータです。
tab-quarantine=> SELECT * FROM delete_from_me;
id | extension
------------+-----------
12345abcde | png
(1 row)
tab-quarantine=> SELECT * FROM constraining_table;
image | type
------------+----------
12345abcde | select_me
(1 row)
そして、ここに私の取引があります:
BEGIN;
\set ON_ERROR_STOP 1
SET CONSTRAINTS ALL DEFERRED;
DELETE FROM delete_from_me WHERE id IN (
SELECT image FROM constraining_table WHERE type = 'select_me'
);
DELETE FROM constraining_table WHERE type = 'select_me';
COMMIT;
このトランザクションは失敗します。ステップスルーしてこれを手動で行うと、次のエラーメッセージが表示されます。
ERROR: update or delete on table "delete_from_me" violates foreign key constraint "constraining_table_image_fkey" on table "constraining_table"
DETAIL: Key (id)=(12345abcde) is still referenced from table "constraining_table".
これは一時テーブルの良い候補のように思えますが、トランザクションの最後まで制約が有効にならないはずなのに、なぜこの順序で削除できないのか知りたいのですが?