PostgreSQL, 'Допускающие задержку, Удаляют' все еще, ограничение хитов на Удаляет

Я хочу удалить строки из двух таблиц, которые имеют зависимость друг от друга через ряд допускающих задержку ограничений. Для упрощения этого сообщения я копировал простую схему 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".

Это походит на хорошего кандидата на временную таблицу, однако я хотел бы знать отчего получается, что я не могу удалить в этом порядке, учитывая ограничения, не должно быть действительно согласно концу транзакции?

6
задан heymatthew 19 July 2010 в 06:17
поделиться

1 ответ

Используйте 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 является отложенным. Вот почему я рекомендовал это - я думаю, это как раз то, о чем вы просите.

7
ответ дан 17 December 2019 в 00:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: