Я хочу удалить строки из двух таблиц, которые имеют зависимость друг от друга через ряд допускающих задержку ограничений. Для упрощения этого сообщения я копировал простую схему DB.
Я надеюсь удалить записи из некоторой таблицы, 'delete_from_me', в Патче транзакции/DB SQL. Выгода, я хочу удалить на основе выбора из второй таблицы 'constraining_table', прежде чем я буду освобождать саму ссылку.
Вот описание этих двух таблиц:
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".
Это походит на хорошего кандидата на временную таблицу, однако я хотел бы знать отчего получается, что я не могу удалить в этом порядке, учитывая ограничения, не должно быть действительно согласно концу транзакции?
Используйте ON DELETE NO ACTION DEFERRABLE
вместо ON DELETE RESTRICT DEFERRABLE
. Использование RESTRICT
вместо NO ACTION
заставляет ограничение быть не отменяемым, независимо от того, применяете ли вы модификатор DEFERRABLE
.
Это написано мелким шрифтом на странице руководства для CREATE TABLE
:
Ссылочные действия, кроме проверки NO ACTION, не могут быть отложены, даже если ограничение объявлено откладываемым.
Очевидно, что вышеприведенное предостережение включает RESTRICT
.
Вскоре после этого предложения следуют определения NO ACTION
и RESTRICT
:
NO ACTION
Выдаст ошибку, указывающую, что удаление или обновление создаст нарушение ограничения внешнего ключа. Если ограничение отложено, эта ошибка будет выдана во время проверки ограничения, если все еще существуют ссылающиеся строки. Это действие по умолчанию.
RESTRICT
Выдать ошибку, указывающую на то, что удаление или обновление создаст нарушение ограничения внешнего ключа. Это то же самое, что и NO ACTION, за исключением того, что проверка не может быть отложена.
Как видите, NO ACTION
будет вести себя идентично RESTRICT
, за исключением того, что NO ACTION
является отложенным. Вот почему я рекомендовал это - я думаю, это как раз то, о чем вы просите.