hey*_*hew 6 sql postgresql transactions cascade
我想删除两个表中的行,这两个表通过一组可延迟的约束相互依赖.为了简化这篇文章,我模拟了一个简单的数据库模式.
我希望在SQL事务/数据库补丁中删除某些表中的条目'delete_from_me'.问题是,我想在松开链接本身之前根据第二个表'constraining_table'中的选择进行删除.
这是两个表的描述:
tab-quarantine=> \d delete_from_me
Table "public.delete_from_me"
Column | Type | Modifiers
-----------+-------------------+-----------
id | character varying | not null
extension | character varying | not null
Indexes:
"delete_from_me_pkey" PRIMARY KEY, btree (id)
tab-quarantine=> \d constraining_table
Table "public.constraining_table"
Column | Type | Modifiers
--------+-------------------+-----------
image | character varying | not null
type | character varying | not null
Foreign-key constraints:
"constraining_table_image_fkey" FOREIGN KEY (image) REFERENCES delete_from_me(id)
ON UPDATE CASCADE
ON DELETE RESTRICT DEFERRABLE
Run Code Online (Sandbox Code Playgroud)
这是我刚刚在那里抨击的一些示例数据:
tab-quarantine=> SELECT * FROM delete_from_me;
id | extension
------------+-----------
12345abcde | png
(1 row)
tab-quarantine=> SELECT * FROM constraining_table;
image | type
------------+----------
12345abcde | select_me
(1 row)
Run Code Online (Sandbox Code Playgroud)
这是我的交易:
BEGIN;
\set ON_ERROR_STOP 1
SET CONSTRAINTS ALL DEFERRED;
DELETE FROM delete_from_me WHERE id IN (
SELECT image FROM constraining_table WHERE type = 'select_me'
);
DELETE FROM constraining_table WHERE type = 'select_me';
COMMIT;
Run Code Online (Sandbox Code Playgroud)
此交易失败.当我单步执行并手动执行此操作时,出现以下错误消息:
ERROR: update or delete on table "delete_from_me" violates foreign key constraint "constraining_table_image_fkey" on table "constraining_table"
DETAIL: Key (id)=(12345abcde) is still referenced from table "constraining_table".
Run Code Online (Sandbox Code Playgroud)
这似乎是临时表的一个很好的候选者,但是我想知道为什么我不能按此顺序删除,因为约束在事务结束之前不应该有效?
用ON DELETE NO ACTION DEFERRABLE而不是ON DELETE RESTRICT DEFERRABLE.无论是否应用修改器,使用RESTRICT而不是NO ACTION强制约束是不可延迟的DEFERRABLE.
这是手册页CREATE TABLE的精细打印:
即使约束被声明为可延迟,也不能延迟除NO ACTION检查以外的参考动作.
显然,上述警告包括RESTRICT.
这句话后不久,以下是定义NO ACTION和RESTRICT:
没有行动
产生错误,指示删除或更新将创建外键约束违规.如果约束被延迟,如果仍存在任何引用行,则将在约束检查时生成此错误.这是默认操作.
限制
产生错误,指示删除或更新将创建外键约束违规.这与NO ACTION相同,但检查不可延迟.
正如您所看到的,除了可延迟之外,其NO ACTION行为方式相同.这就是我推荐它的原因 - 我认为这正是你所要求的.RESTRICTNO ACTION
| 归档时间: |
|
| 查看次数: |
2386 次 |
| 最近记录: |