级联删除一次
时间:2020-03-06 14:41:01 来源:igfitidea点击:
我有一个Postgresql数据库,我想在该数据库上进行一些级联删除。但是,这些表未使用ON DELETE CASCADE规则进行设置。有什么办法可以执行一次删除并告诉Postgresql一次将其级联吗?相当于
DELETE FROM some_table CASCADE;
这个较旧问题的答案似乎似乎不存在这样的解决方案,但我想我想明确地问这个问题只是为了确定。
解决方案
只需一次,我们只需为要级联的表编写delete语句即可。
DELETE FROM some_child_table WHERE some_fk_field IN (SELECT some_id FROM some_Table); DELETE FROM some_table;
带级联选项的删除仅适用于已定义外键的表。如果我们执行删除操作,但说不能,因为它会违反外键约束,则级联将导致它删除有问题的行。
如果要以这种方式删除关联的行,则需要首先定义外键。另外,请记住,除非我们明确指示它开始事务,或者更改默认值,否则它将执行自动提交,这可能会非常耗时。
如果我理解正确,那么我们应该能够通过删除外键约束,添加新的(它将层叠),完成工作并重新创建限制性外键约束来做我们想要的事情。
例如:
testing=# create table a (id integer primary key);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "a_pkey" for table "a"
CREATE TABLE
testing=# create table b (id integer references a);
CREATE TABLE
-- put some data in the table
testing=# insert into a values(1);
INSERT 0 1
testing=# insert into a values(2);
INSERT 0 1
testing=# insert into b values(2);
INSERT 0 1
testing=# insert into b values(1);
INSERT 0 1
-- restricting works
testing=# delete from a where id=1;
ERROR: update or delete on table "a" violates foreign key constraint "b_id_fkey" on table "b"
DETAIL: Key (id)=(1) is still referenced from table "b".
-- find the name of the constraint
testing=# \d b;
Table "public.b"
Column | Type | Modifiers
--------+---------+-----------
id | integer |
Foreign-key constraints:
"b_id_fkey" FOREIGN KEY (id) REFERENCES a(id)
-- drop the constraint
testing=# alter table b drop constraint b_a_id_fkey;
ALTER TABLE
-- create a cascading one
testing=# alter table b add FOREIGN KEY (id) references a(id) on delete cascade;
ALTER TABLE
testing=# delete from a where id=1;
DELETE 1
testing=# select * from a;
id
----
2
(1 row)
testing=# select * from b;
id
----
2
(1 row)
-- it works, do your stuff.
-- [stuff]
-- recreate the previous state
testing=# \d b;
Table "public.b"
Column | Type | Modifiers
--------+---------+-----------
id | integer |
Foreign-key constraints:
"b_id_fkey" FOREIGN KEY (id) REFERENCES a(id) ON DELETE CASCADE
testing=# alter table b drop constraint b_id_fkey;
ALTER TABLE
testing=# alter table b add FOREIGN KEY (id) references a(id) on delete restrict;
ALTER TABLE
当然,为了心理健康,我们应该将类似的内容抽象到一个过程中。
与注释一起使用:如注释中所指出:"这将删除对some_table具有外键约束的所有表的所有行,以及对这些表具有约束的所有表,等等"
在Postgres上,假设我们不想指定WHERE子句,则可以使用TRUNCATE命令:
TRUNCATE some_table CASCADE;
方便地,这是事务性的(即可以回滚),尽管它与其他并发事务没有完全隔离,并且还有其他一些警告。阅读文档以获取详细信息。

