更改和更新层次关系表以查看是不是有子级的过程

Posted

技术标签:

【中文标题】更改和更新层次关系表以查看是不是有子级的过程【英文标题】:Procedure to alter and update table on hierarchical relationship to see if there are any children更改和更新层次关系表以查看是否有子级的过程 【发布时间】:2010-03-18 14:27:14 【问题描述】:

我在 Oracle pl/sql 上有一个分层表。类似:

create table hierarchical (
   id             integer primary key,
   parent_id          references hierarchical ,
   name           varchar(100));

我需要创建一个过程来更改该表,以便获得一个新字段,该字段告诉每个节点是否有任何子节点。

是否可以在一个过程中进行更改和更新? 任何代码示例将不胜感激。

谢谢

【问题讨论】:

【参考方案1】:

您不能一步完成ALTER TABLE (DDL) 和UPDATE (DML)。

您必须先输入ALTER TABLE,然后输入UPDATE

BEGIN
  EXECUTE IMMEDIATE 'ALTER TABLE hierarchical ADD child_count INTEGER';
  --
  EXECUTE IMMEDIATE '
  UPDATE hierarchical h
  SET child_count = ( SELECT COUNT(*)
                      FROM hierarchical h2
                      WHERE h2.parent_id = h.id )';
END;

不过,在这样做之前要三思而后行。您现在可以轻松找出 id 是否有任何子代查询。

这会给你所有***节点的子数,例如:

SELECT h.id, h.name, COUNT(childs.id) child_count
FROM hierarchical h
LEFT JOIN hierarchical childs ON ( childs.parent_id = h.id )
WHERE h.parent_id IS NULL
GROUP BY h.id, h.name

添加包含冗余数据的额外列将使更改数据变得更加困难,因为在添加/删除子项时,您也必须始终更新父项。

【讨论】:

表中的数据不会经常变化。事实上它可能永远不会改变。关于该查询的问题是,如果我得到例如所有根节点并且我想知道每个根节点是否有子节点,我将不得不执行与根节点数量相同的查询次数。是不是可以使用类似的东西:execute immediate 'alter table'... 一步完成? @tr-raziel:编辑了我的答案以解释它是如何使用EXECUTE IMMEDIATE 工作的,但我还添加了一个查询,该查询应该为您提供所有根节点的正确计数。 非常感谢。我明白你现在想说什么。 你的方式!这样做对我来说的问题是映射到 JPA 之后我必须做,但我认为无论如何我不会有那么大的麻烦。【参考方案2】:

如果您只需要知道子项是否存在,以下查询可以在没有循环或非规范化列的情况下完成。

    select h.*, connect_by_isleaf as No_children_exist
      from hierarchical h
start with parent_id is null
connect by prior id = parent_id; 

如果行有子行,CONNECT_BY_LEAF 返回 0,如果没有,则返回 1。

我认为您可以通过巧妙地使用分析函数和 LEVEL 伪列来获得确切的孩子数量,但我不确定。

【讨论】:

以上是关于更改和更新层次关系表以查看是不是有子级的过程的主要内容,如果未能解决你的问题,请参考以下文章

使用 D3.js 的层次力图

js实现多级复选框的交互

更新 SQL Server 表以通过存储过程执行此操作

css父级没包住子级是怎么回事,我用firebug查看,确实在父级的div中,但是就是没有包括子级的内容

Android - 查看子项数量更改时的侦听器/回调

属于 UserControl 子级的错误与 UserControl 而不是子级相关联