Postgresql при удалении каскада

У меня есть две таблицы, TableY - идентификатор, имя, описание TableX - id, name, y_id

Я добавил внешний ключ в таблицу X (y_id, ссылающийся на таблицуY id ON DELETE CASCADE). Когда я удаляю из таблицы X, идентификатор TableY остается (хотя его теоретически следует удалить). Наверное, я неправильно понял, как работает опция DEL DELETE CASCADE. Может ли кто-нибудь сказать, что я делаю неправильно?

Я видел это ON DELETE CASCADE, но не имел большого смысла для меня.

Ответ 1

Я думаю, у вас возникло недоразумение. Попробуйте удалить строку из TableY, а соответствующие строки из TableX будут удалены каскадом. Этот параметр необходим, если у вас есть вторичные связанные таблицы, и вы хотите очистить их все, удалив родительскую строку из первичной таблицы, не нарушая ограничений или не удаляясь.

Ответ 2

Короткий ответ

ON DELETE CASCADE указывает опцию ограничения. В вашем случае (предположим, что у вас есть table_x и table_y, которые зависят от table_x), когда вы удаляете строку в таблице_x, и эта строка ссылается на таблицу_y, строка из таблицы_x будет удалена, и все строки, ссылающиеся на эту строку в таблице_y, также будут удалены.

Если вы хотите удалить таблицу и в этой таблице зависеть одна или несколько других таблиц, используйте DROP TABLE с ключевым словом CASCADE.

Подробнее о параметрах DROP, DELETE и ON DELETE CASCADE

Drop vs delete

Если вы хотите удалить таблицу из базы данных, используйте слово drop. Когда вы используете слово delete, это означает, что вы хотите удалить/удалить содержимое из таблицы (но хотите, чтобы таблица оставалась = продолжать существовать в базе данных).

Удаление строки, ссылающейся на другую таблицу

Когда у вас есть строка в таблице (например, table_x и строка с идентификатором 1), и эта строка ссылается на другую таблицу (в другой таблице есть внешний ключ, связанный с этой записью), вы не можете удалить следующую строку. Вы получите сообщение об ошибке.

DELETE FROM table_x WHERE id = 1;

ERROR:  update or delete on table "table_x" violates foreign key constraint "constraint_name" on table "table_y"
DETAIL:  Key (id)=(1) is still referenced from table "table_y".

Причина описана в детальной части ошибки. Запись/записи в другой таблице/таблицах ссылаются на эту запись. В качестве примера вы можете представить табличную учетную запись и таблицу account_activity. Когда вы удаляете запись из учетной записи таблицы (вы удаляете одну учетную запись), вы должны удалить все записи из таблицы account_activity, ссылающиеся на эту конкретную запись в табличной учетной записи. Если вы не закончили работу с учетной записью, которая не относится к какой-либо учетной записи.

В зависимости от того, чего вы хотите достичь, есть две возможности:

  • Вы хотите удалить содержимое всей таблицы (table_x) и содержимого все таблицы, имеющие ссылку (внешний ключ) в эту таблицу.
  • Вы хотите удалить одну или несколько записей (строк), указанных в предложении WHERE, из одной таблицы, а также удалить все строки, ссылающиеся на это запись/записи (например, пример с учетной записью и account_activity упомянутый выше).

1) Используйте TRUNCATE с ключевым словом CASCADE

TRUNCATE table_x CASCADE;

2) Измените ограничение, которое у вас есть в таблице_y на столбце, чтобы иметь опцию ON DELETE CASCADE.

ALTER TABLE table_y   
    DROP CONSTRAINT constraint_name,   
    ADD CONSTRAINT constraint_name FOREIGN KEY (column_in_table_y)
          REFERENCES table_x (referenced_column_in_table_x) ON DELETE CASCADE;

Отбрасывающая таблица, от которой зависят другие таблицы

Когда у вас есть таблица (например, table_x) и другая таблица/таблицы, зависит от нее, вы не можете удалить эту таблицу. В зависимости от того, что другие таблицы ссылаются (имеют внешний ключ) к этой таблице (table_x). Когда вы пытаетесь удалить такую ​​таблицу, вы получаете ошибку.

DROP TABLE table_x;

ERROR:  cannot drop table table_x because other objects depend on it
DETAIL:  constraint id_x_fk on table table_y depends on table table_x
HINT:  Use DROP ... CASCADE to drop the dependent objects too.

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

DROP TABLE table_x CASCADE;

<сильные > Примеры

Создает table_x и table_y.

CREATE TABLE table_x
(
  id integer NOT NULL,
  text character varying(255) NOT NULL,
  CONSTRAINT table_x_pk PRIMARY KEY (id)
);

CREATE TABLE table_y
(
  id integer NOT NULL,
  text character varying(255) NOT NULL,
  id_x integer NOT NULL,
  CONSTRAINT table_y_pk PRIMARY KEY (id)
);

Создает ограничение с именем id_x_fk в столбце id_x в таблице_y.

ALTER TABLE table_y
  ADD CONSTRAINT id_x_fk FOREIGN KEY (id_x)
      REFERENCES table_x (id);

Вставляет данные теста в table_x и table_y.

INSERT INTO table_x VALUES
    (1, 'super x'),
    (2, 'great x');

INSERT INTO table_y VALUES
    (1, 'y one', 2),
    (2, 'y two', 1),
    (3, 'y three', 1);

Удаление из таблицы_x (ошибка).

DELETE FROM table_x WHERE id = 1;

Удаление и добавление ограничения с тем же именем.

ALTER TABLE table_y
  DROP CONSTRAINT id_x_fk,
  ADD CONSTRAINT id_x_fk FOREIGN KEY (id_x)
      REFERENCES table_x (id) ON DELETE CASCADE;

Удаление из таблицы_x, а также из таблицы_y (правильно).

DELETE FROM table_x WHERE id = 1;

Удаление всего содержимого из table_x и table_y.

TRUNCATE table_x CASCADE;

Удаление (удаление) table_x и удаление ограничения id_x_fk в таблице_y.

DROP TABLE table_x CASCADE;

Примечание

Если у вас есть строка в table_x (например, с id = 3), и эта запись (этот идентификатор) не ссылается на таблицу_y, вы можете удалить строку, даже если ограничение не имеет опции DEL DELETE CASCADE (потому что нет ограничений нарушение).

Код был протестирован на "PostgreSQL 9.2.4, скомпилированном Visual С++ build 1600, 64-bit".

Источники:

http://www.postgresql.org/docs/current/static/sql-droptable.html

http://www.postgresql.org/docs/current/static/sql-delete.html

http://www.postgresql.org/docs/current/static/ddl-constraints.html

http://www.postgresql.org/docs/current/static/sql-altertable.html

PostgreSQL удалить весь контент