0

我在 Oracle pl/sql 上有一个分层表。就像是:

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

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

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

谢谢

4

2 回答 2

2

您不能一步完成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

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

于 2010-03-18T14:37:41.657 回答
0

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

    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 伪列来获得确切的孩子数量,但我不确定。

于 2010-03-18T17:25:08.103 回答