级联删除一次
时间: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;
方便地,这是事务性的(即可以回滚),尽管它与其他并发事务没有完全隔离,并且还有其他一些警告。阅读文档以获取详细信息。