简短的回答
ON DELETE CASCADE 指定约束选项。在您的情况下(假设您有依赖于 table_x 的 table_x 和 table_y)当您删除 table_x 中的行并且从 table_y 引用该行时,table_x 中的行将被删除,并且在 table_y 中引用该行的所有行也将被删除。
当您要删除表并在此表上依赖一个或多个其他表时,请使用 DROP TABLE 和 CASCADE 关键字。
有关 DROP、DELETE 和 ON DELETE CASCADE 约束选项的更多信息
删除与删除
当您想从数据库中删除表时,请使用 word drop。当您使用单词 delete 时,表示您要从表中删除/删除内容(但希望表保持 = 继续存在于数据库中)。
删除从其他表引用的行
当您在表中有行(例如 table_x 和 id 为 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 和表 account_activity。当您从表帐户中删除条目(删除一个帐户)时,您应该从表 account_activity 中删除所有引用表帐户中此特定条目的条目。如果不是,您最终会得到不涉及任何帐户的帐户活动。
根据您想要实现的目标,有两种可能性:
- 您要删除整个表 (table_x) 的内容和所有对该表有引用(外键)的表的内容。
- 您想从一个表中删除 WHERE 子句中指定的一个或多个条目(行),并删除所有引用此条目的行(如上面提到的 account 和 account_activity 的示例)。
1) 使用带有 CASCADE 关键字的 TRUNCATE
TRUNCATE table_x CASCADE;
2) 更改您在 table_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)
);
在 table_y 的列 id_x 上创建名称为 id_x_fk 的约束。
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);
从 table_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;
从 table_x 和 table_y 中删除(正确)。
DELETE FROM table_x WHERE id = 1;
删除 table_x 和 table_y 中的所有内容。
TRUNCATE table_x CASCADE;
删除(删除)table_x 并删除 table_y 中的 id_x_fk 约束。
DROP TABLE table_x CASCADE;
注意
如果您在 table_x 中有行(例如,id = 3)并且此条目(此 id)未从 table_y 引用,您可以删除该行,即使约束没有 ON DELETE CASCADE 选项(因为没有违反约束)。
该代码在“PostgreSQL 9.2.4,由 Visual C++ 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 删除所有内容