zoukankan      html  css  js  c++  java
  • oracle 层次化查询(生成菜单树等)

    1、简介:Oracle层次化查询是Oracle特有的功能实现,主要用于返回一个数据集,这个数据集存在树的关系(数据集中存在一个Pid记录着当前数据集某一条记录的Id)。

    2、层次化查询主要包含两个子句,一个start with另一个是connect by。

    start with:这个子句一般用于指定层次化查询的开始节点(也就是树的最顶级节点),找到最顶级节点,然后按照一定的规则开始查找其剩余的子节点

    connect by:这个子句就是上面所说的规则,用于查找剩余子节点的规则

    CREATE TABLE MENU
    (    "ID" NUMBER, 
        "DATA" VARCHAR2(100), 
        "PID" NUMBER
    ) 
    insert into MENU (id, data, pid)values (7, 'g', 3);
    insert into MENU (id, data, pid)values (1, 'a', null);
    insert into MENU (id, data, pid)values (2, 'b', null);
    insert into MENU (id, data, pid)values (3, 'c', 2);
    insert into MENU (id, data, pid)values (4, 'd', 2);
    insert into MENU (id, data, pid)values (5, 'e', 4);
    insert into MENU (id, data, pid)values (6, 'f', 1);

    下面开始执行层次化查询,从PId为null的节点(该节点为根节点)开始递归查找,查找出所有的更节点下的子节点,构建出一个完整的树

    select ID,DATA,nvl(TO_CHAR(PID),'NULL') from menu start with PID is NULL connect by prior ID=pid

    代码解析:

    (1)、start with PID is NULL  指定层次化查询的根节点,

    红框内的两个节点为根节点,并开始遍历其余的节点。

    (2)、connect by prior ID=pid  当前节点的PID等于上一层节点的ID,如果满足条件,就加入到树结果集中

    指定遍历查找子节点的规则----->  这一过程是递归查找,会一层一层找下去,直到不符合这一规则,则查找停止。

    3、实现上面结果集的另一种Sql实现

    select ID,DATA,nvl(TO_CHAR(PID),'NULL') from menu start with (data='a' or data='b') connect by prior ID=PID

    结论:根节点的定义比较灵活,但是(connect by)遍历子节点的规则,比较固定基本都是判断父节点和子节点的ID的,如果理解了这句话,层次化查询,差不多也就理解了!

    4、  Oracle SQL 中的层次化查询会检测数据中是否存在回环(死循环),如果存在回环,则会抛出 ORA-01436: CONNECT BY loop in user data 的错误。如果在 connect by 后面加上 nocycle 则 产生回环的最后一层的节点会被删除。

    如果数据中出现这种情况,产生了回环,那么在connect by 后面 加nocycle,节能

    select ID,DATA,nvl(TO_CHAR(PID),'NULL') from menu start with (data='a' or data='b') connect by nocycle prior ID=PID 

     

    just没有报错,有点郁闷,并没有删除,不知道哪里出了问题,但是至少不抱错了!!!

    5、Oracle 还为层次化查询提供了一些伪列( Pseudo Column )。

    (1)、CONNECT_BY_ISCYCLE 当这一行有一个子节点同时也是它的祖先节点时返回 1 ,否则返回 0 

    (2)、CONNECT_BY_ISLEAF 当这一行是叶节点时返回 1 ,否则返回 0 。伪列 LEVEL 返回这一行在树中的层次,根为第一层。

    (3)、CONNECT_BY_ROOT 查询操作符可以加在 connect by 之后的某个字段之前,表示获得这一行的根节点的该字段的值。

    6、层次化查询还支持一个特殊的函数 SYS_CONNECT_BY_PATH , SYS_CONNECT_BY_PATH ( exp , char ),这个函数返回从根节点到这一行计算其中每个exp 表达式的值,并把它们连接成字符串,每个节点之间用 char 字符来分割。下面是一个例子。

    这个函数很棒,可以考虑其他的数据库也实现这个方法,这样我们处理一个树结构就很方便了!!!

  • 相关阅读:
    ASP.NET CORE 使用Consul实现服务治理与健康检查(2)——源码篇
    ASP.NET CORE 使用Consul实现服务治理与健康检查(1)——概念篇
    Asp.Net Core 单元测试正确姿势
    如何通过 Docker 部署 Logstash 同步 Mysql 数据库数据到 ElasticSearch
    Asp.Net Core2.2 源码阅读系列——控制台日志源码解析
    使用VS Code 开发.NET CORE 程序指南
    .NetCore下ES查询驱动 PlainElastic .Net 升级官方驱动 Elasticsearch .Net
    重新认识 async/await 语法糖
    EF添加
    EF修改部分字段
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/6551440.html
Copyright © 2011-2022 走看看