Sql 检测对删除的依赖关系
我想从不存在外键依赖项的表中删除行。如果它们确实存在,则应将行标记为“deadfield”,以保持关系完整性。目标是只保留必要的数据 删除只会影响一行;它不会触发级联删除,我也不会尝试删除依赖项。例如,客户行在许多其他表(如发票、协议、变更单等)中被引用,该客户行应标记为“deadfield”。如果没有此类引用,则可以从表中删除客户行 我正在从客户端应用程序代码中寻找关于处理此问题的最佳方法的建议。我正在使用PostgreSQL 9.1 以下是当前的方法,它依赖于Postgres对外键依赖关系的“知识”:Sql 检测对删除的依赖关系,sql,postgresql,Sql,Postgresql,我想从不存在外键依赖项的表中删除行。如果它们确实存在,则应将行标记为“deadfield”,以保持关系完整性。目标是只保留必要的数据 删除只会影响一行;它不会触发级联删除,我也不会尝试删除依赖项。例如,客户行在许多其他表(如发票、协议、变更单等)中被引用,该客户行应标记为“deadfield”。如果没有此类引用,则可以从表中删除客户行 我正在从客户端应用程序代码中寻找关于处理此问题的最佳方法的建议。我正在使用PostgreSQL 9.1 以下是当前的方法,它依赖于Postgres对外键依赖关系的
Begin transation
delete row x
if SQLSTATE Error Code = 23503
update row set deadfiled = true
if success
commit transaction
else rollback
在一些帖子中,上述方法似乎被认为是脆弱的。有更好的方法吗?我从来没有真正使用过PostgreSQL,但看起来您使用的是基于光标的方法 不如换一种基于集合的解决方案 运行更新查询,检查是否存在依赖项并标记这些记录
update parent
set deadfiled = true
where
exists (
select *
from dependency1 as d1
where d1.id = parent.id
)
or
exists (
select *
from depenedency2 as d2
where d2.id = parent.id
)
--or ... etc., keep adding dependency checks
。。。然后删除未设置标志的内容:
delete from parent where deadfiled = false
当然,您的建议是有效的,但是如果关系涉及多个表,则需要大量编码。阅读您的问题后,我意识到您认为我正在删除依赖项。这不是你想要的。@no,我看到你想要删除依赖的,而不是依赖的。您提出了一个很好的观点,即当存在大量依赖项时需要付出的努力。我正在搜索是否存在
SET QUIT containing ABOUT FAILED DELETES AND FINISH SUCCESSFUL DELETES=ON
选项,这将非常方便feature@J库珀:仅供参考,MySQL有DELETE IGNORE
,它就是这样做的,它删除所有可以删除的内容,只忽略由于外键约束而无法删除的行。不幸的是,PostgreSQL没有这个功能,所以这并不是这个问题的答案。为什么不总是设置deadfield
,而不考虑是否存在依赖项呢?无论如何,您都必须筛选死区
,以将活动行与僵尸行分开。我怀疑物理删除某些行是否会给您带来任何可测量的性能提升。或者这样做,然后执行一些“清理”任务来删除未引用的死行。你甚至可以称之为“自动真空”;)