我有一个示例情况:父
表有一个名为id
的列,在子
表中作为外键引用。
删除子行时,如果父行未被任何其他子行引用,如何删除父行?
delete from child
where parent_id = 1
在子项中删除后,在父项中删除:
delete from parent
where
id = 1
and not exists (
select 1 from child where parent_id = 1
)
不存在
条件将确保它仅在子级中不存在时才会被删除。您可以将两个删除命令包装在事务中:
begin;
first_delete;
second_delete;
commit;
在PostgreSQL 9.1或更高版本中,您可以使用使用数据修改CTE的单个语句来执行此操作。这通常不太容易出错。它最大限度地减少了两个DELETE之间的时间框架,其中竞争条件可能会导致并发操作的惊人结果:
sql prettyprint-override">WITH del_child AS (
DELETE FROM child
WHERE child_id = 1
RETURNING parent_id, child_id
)
DELETE FROM parent p
USING del_child x
WHERE p.parent_id = x.parent_id
AND NOT EXISTS (
SELECT 1
FROM child c
WHERE c.parent_id = x.parent_id
AND c.child_id <> x.child_id -- !
);
数据库
在任何情况下都会删除该子项。我引用手册:
with
中的数据修改语句只执行一次,并且始终执行到完成,与主查询是否读取其所有(或任何)输出无关。请注意,这与with
中SELECT
的规则不同:如上一节所述,SELECT
的执行仅在主查询需要其输出的范围内进行。
注意最后一个条件。与预期相反,这是必要的,因为:
和
中的子语句与主查询同时执行。因此,当使用<code>中的数据修改语句时,指定更新实际发生的顺序是不可预测的。所有语句都使用相同的快照执行(参见第13章),因此它们无法“看到”彼此对目标表的影响。
我用列名parent_id
代替了非描述性的id
。
为了完全消除上面提到的可能的争用条件,首先锁定父行。当然,所有类似的操作都必须遵循相同的程序才能工作。
WITH lock_parent AS (
SELECT p.parent_id, c.child_id
FROM child c
JOIN parent p ON p.parent_id = c.parent_id
WHERE c.child_id = 12 -- provide child_id here once
FOR NO KEY UPDATE -- locks parent row.
)
, del_child AS (
DELETE FROM child c
USING lock_parent l
WHERE c.child_id = l.child_id
)
DELETE FROM parent p
USING lock_parent l
WHERE p.parent_id = l.parent_id
AND NOT EXISTS (
SELECT 1
FROM child c
WHERE c.parent_id = l.parent_id
AND c.child_id <> l.child_id -- !
);
这样,一次只有一个事务可以锁定同一个父事务。因此,多个事务删除同一父级的子项,仍然看到其他子项并保留父项,而所有子项之后都消失了,这是不可能的。(对于无密钥更新,仍允许对非密钥列进行更新
。
如果这种情况从未发生过,或者您可以忍受它(几乎从未发生过)发生——第一个查询更便宜。否则,这是安全路径。
Postgres 9.4中引入了< code>FOR NO KEY UPDATE。手册中有详细说明。在旧版本中,请改用更强的锁< code>FOR UPDATE。
我尝试了第二个查询的子表的-join,但它没有给出理想的结果。 我的第一个查询工作良好,我得到了正确的父列表,我的问题是没有得到所有的孩子当我运行第二个查询。如何解决这个问题?
本文向大家介绍如何使用jQuery从父级删除所有子级节点?,包括了如何使用jQuery从父级删除所有子级节点?的使用技巧和注意事项,需要的朋友参考一下 要从父级删除所有子节点,请使用方法。该方法从匹配的元素集中删除所有子节点。 示例 您可以尝试运行以下代码以了解如何从父级删除所有子节点-
问题内容: 假设我们有3个Entities对象类: 如何使用JPA2.x(或hibernate)批注来: 父级删除时(一对多)自动删除所有子级 删除后自动从子级列表中删除子级(多对一) 儿童删除时(一对一)自动删除玩具 我正在使用Hibernate 4.3.5和mysql 5.1.30。 谢谢 问题答案: 如本文所述, 实体状态转换应从父级到子级联,而不是相反。 您需要这样的东西:
问题内容: 我要删除,因此要从数据库中删除行。 我 确实 要删除某个实体及其所有行。不过,我 不 希望从它删除任何行。 如何 我能做到这一点? 是,并且是我要删除的实体。 请参阅下面的代码,了解我如何在“狗窝实体”中链接2: 目前,当我删除狗entitie(S),其相关的养犬实体 中 也被删除。 编辑:将狗映射到狗窝: 问题答案: 当前,当我删除狗实体时,其相关的狗窝实体也将被删除。 原因是您已设
我有两个实体使用Spring和Hibernate
我试图递归删除JSON对象和所有子对象中的空值。如果子对象的关键点都已删除,则我希望该子对象也被删除。 比如。 应该变成这样: 下面是我编写的删除所有空值键的函数: 但这不会删除没有子项的父项: 因此,我得到的不是上面的结果,而是: 如您所见,它不会删除申请人的密钥。我如何在函数中检查它?或者它是否需要编写在我调用delKeys()后调用的单独函数中? 还有,有人看到这达到了最大递归深度吗?我尝试