Задание отложенного ограничения не работает в транзакции PostgreSQL - PullRequest
13 голосов
/ 22 февраля 2011

Это ситуация: у меня есть две таблицы, где одна ссылается на другую (скажем, таблица2 ссылается на таблицу1).При создании этих таблиц я установил ограничение внешнего ключа как DEFERRABLE, а предложения ON UPDATE и ON DELETE - как НЕТ ДЕЙСТВИЯ (по умолчанию).

Но все же при выполнении транзакции ниже я получаюследующая ошибка.

Транзакция:

START TRANSACTION;
SET CONSTRAINTS ALL DEFERRED;
UPDATE table1 SET blah blah;
UPDATE table2 SET blah blah;
COMMIT;

Ошибка:

ERROR:  update or delete on table "table1" violates foreign key constraint "table1_column_fkey" on table "table2"
DETAIL:  Key (column1)=(blahblah) is still referenced from table "table2".

И построение таблицы:

CREATE TABLE table1(
    column1 CHAR(10),
    [...]
    PRIMARY KEY (column1)
);

CREATE TABLE table2(
    primkey CHAR(9),
    [...]
    column2 CHAR(10) NOT NULL,
    PRIMARY KEY(primkey),
    FOREIGN KEY(column2) REFERENCES table1(column1) DEFERRABLE
);

Что я хочу сделать, этоотложить проверку внешнего ключа во время выполнения транзакции до ее фиксации.Я просто не понимаю, почему возвращается эта ошибка и как заставить транзакцию работать.

1 Ответ

7 голосов
/ 28 февраля 2011

Проблема действительно в нарушении ограничения внешнего ключа. Я имею в виду, что ограничения действительно были отложены внутри транзакции, но проблема заключалась в том, что в конце транзакции, после обновления таблиц1 и таблиц2, новые данные нарушали ограничение внешнего ключа. Я обновлял первичный ключ строки table1, на которую все еще ссылались некоторые строки таблицы table2. Эти строки мне тоже пришлось обновить, чтобы ссылочный столбец строк таблицы2 соответствовал обновленному первичному ключу строки таблицы1. Я изменил запросы «ОБНОВЛЕНИЕ» внутри транзакции, и проблема была решена.

Извините, что помещаю вас в это. Решение было таким простым, но в тот день я его не увидел.

...