Подтвердить что ты не робот

Удаление строк с внешним ключом в PostgreSQL

Я хотел бы удалить строки, содержащие внешний ключ, но когда я попробую что-то вроде этого:

DELETE FROM osoby WHERE id_osoby='1'

Я получаю следующее утверждение:

ОШИБКА: обновление или удаление в таблице "osoby" нарушает ограничение внешнего ключа "kontakty_ibfk_1" на таблице "kontakty" ДЕТАЛИ: Ключ (id_osoby) = (1) по-прежнему ссылается на таблицу "kontakty".

Как удалить эти строки?

4b9b3361

Ответ 1

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

CASCADE указывает, что при удалении ссылочной строки строки, ссылающиеся на нее, также должны автоматически удаляться.

Посмотрите текущее определение FK следующим образом:

SELECT pg_get_constraintdef(oid) AS constraint_def
FROM   pg_constraint
WHERE  conrelid = 'public.kontakty'::regclass  -- assuming pubic schema
AND    conname = 'kontakty_ibfk_1';

Затем добавьте или измените часть ON DELETE... в ON DELETE CASCADE (сохраняя все остальное как есть) в таком выражении, как:

ALTER TABLE kontakty
   DROP CONSTRAINT kontakty_ibfk_1
 , ADD  CONSTRAINT kontakty_ibfk_1
   FOREIGN KEY (id_osoby) REFERENCES osoby (id_osoby) ON DELETE CASCADE;

Поскольку синтаксис ALTER CONSTRAINT отсутствует, ALTER CONSTRAINT и заново ALTER CONSTRAINT ограничение в одном операторе ALTER TABLE. Это позволяет избежать возможных условий гонки с одновременным доступом к записи.

Вам нужны привилегии, чтобы сделать это, очевидно. Операция принимает блокировку ACCESS EXCLUSIVE для таблицы kontakty и блокировку SHARE ROW EXCLUSIVE для таблицы osoby.

Если вы не можете ALTER таблицы, затем удалить вручную (один раз) или триггер BEFORE DELETE (каждый раз) Перечислим остальные варианты.

Ответ 2

Вы не можете удалить внешний ключ, если он все еще ссылается на другую таблицу. Сначала удалите ссылку

delete from kontakty
where id_osoby = 1;

DELETE FROM osoby 
WHERE id_osoby = 1;

Ответ 3

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

В моем случае я в режиме разработки и имею пару таблиц, которые ссылаются друг на друга через внешние ключи. Таким образом, удаление их содержимого не так просто, как удаление всех строк из одной таблицы перед другой. Итак, для меня это сработало, чтобы удалить их содержимое следующим образом:

ALTER TABLE table1 DISABLE TRIGGER ALL;
ALTER TABLE table2 DISABLE TRIGGER ALL;
DELETE FROM table1;
DELETE FROM table2;
ALTER TABLE table1 ENABLE TRIGGER ALL;
ALTER TABLE table2 ENABLE TRIGGER ALL;

Вы должны иметь возможность добавлять предложения WHERE по своему усмотрению, конечно, с осторожностью, чтобы не подрывать целостность базы данных.

Там есть хорошее, связанное обсуждение на http://www.openscope.net/2012/08/23/subverting-foreign-key-constraints-in-postgres-or-mysql/

Ответ 4

Прошло некоторое время с тех пор, как этот вопрос был задан, надежда может помочь Поскольку вы не можете изменить или изменить структуру БД, вы можете сделать это. в соответствии с документами postgresql.

TRUNCATE - очистить таблицу или набор таблиц.

TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ]
    [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]

Описание

TRUNCATE быстро удаляет все строки из набора таблиц. Он имеет тот же эффект, что и неквалифицированный DELETE для каждой таблицы, но поскольку он на самом деле не сканирует таблицы, он работает быстрее. Кроме того, он немедленно восстанавливает дисковое пространство, а не требует последующей операции VACUUM. Это наиболее полезно на больших столах.


Усечьте таблицу othertable и каскадно добавьте любые таблицы, которые ссылаются на othertable с помощью ограничений внешнего ключа:

TRUNCATE othertable CASCADE;

То же самое, а также сбросить все связанные генераторы последовательности:

TRUNCATE bigtable, fattable RESTART IDENTITY;

Усечение и сброс любых связанных генераторов последовательностей:

TRUNCATE revinfo RESTART IDENTITY CASCADE ;

Ответ 5

Это означает, что в таблице kontakty у вас есть строка, ссылающаяся на строку в osoby, которую вы хотите удалить. Вы сначала удалили эту строку или установили каскадное удаление в отношении между таблицами.

Powodzenia!