基本介绍

说明:

目前支持的层次查询中,除了存在环的情况,其它情况基本都和ORACLE兼容, 但在某些方面可能也有一些限制,这里先对层次查询做一个总体介绍, 再在相应的地方对特定的限制进行详细说明。

层次查询目前支持三个伪列LEVEL、CONNECT_BY_ISCYCLE和CONNECT_BY_ISLEAF, 两个关键字PRIOR和CONNECT_BY_ROOT,以及一个函数SYS_CONNECT_BY_PATH, 某些的用法有些限制,在以后相应的地方再做详细介绍。 还支持NOCYCLE参数,这个参数可以使层次查询在存在环的情况下继续查询,这给检查数据错误提供了方便。

层次查询有五个重要的可配置参数:

HIERAR_QUERY_MEM

用于配置在层次查询过程中使用的最多内存大小, 该参数可以指定的范围是64——2*1024*1024之间,表示可使用的内存为64K——2G之间。 如果该参数指定过小,可能层次查询因内存不足而使用外存模式执行, 这可能就降低了层次查询的速度。默认情况下该参数为1024, 表示最多可以使用1M的内存,这是一个使用内存查询和外存查询的界限, 使用的范围超过1M,完全属于正常。

HIERAR_QUERY_MAXLEVEL

用于指定层次查询可处理的最多层次数,缺省情况下该参数为1024, 也就是层次数超过1024以后不再处理,而是报错退出。 ORACLE虽然支持层次很多,但其效率并不高,而且平时用到的层次也不会太多。 如果你确实需要很多层次,你可以修改此参数以满足你的要求, 目前可以设置的最大层次数为:1024*1024。如果这个值还是无法满足你的要求,那只能与开发商联系!

HIERAR_QUERY_PATH_MAXLEN

由于SYS_CONNECT_BY_PATH是一个函数,其返回从根到叶节点的路径字符串, 由于该字符串可能很长,所以处理速度会随着层次的增加而变慢, 为了提高查询速度,对PATH的长度做了限制。 如果PATH长度超过HIERAR_QUERY_PATH_MAXLEN的值,就不再处理该应用, 这时候你应该先检查是否确实需要此PATH。 如果不需要可以去掉该函数返回的列来去掉报告的错误; 如果你确实需要此列内容,你可以试着增加该值来解决此问题, 但HIERAR_QUERY_PATH_MAXLEN的可设置范围是1024——8000, 如果你的PATH超过8000,这个版本无法处理你的应用。

HIERAR_RELEASE_MEMSIZE_ONCE

在层次查询的表很大的情况下,HIERAR_QUERY_MEM给出的内存不足以装下所有的记录, 这时需要写出去一些记录,来释放一些空间,保证查询的继续进行。 HIERAR_RELEASE_MEMSIZE_ONCE参数用于控制在往外存写的时候一次释放的内存空间。

ENABLE_HIERAR_USE_MINMEM

在往外存写记录的时候,为了提高查询速度,在内存中保留一些记录是必须的, 但如果查询的表设计到的列很长,保存这些记录就会把所有的可用空间用掉, 这时候内存中不应该保存除管理结构外的任何记录, 这个参数就是用于控制释放所有的记录信息,只在内存中保留管理信息。

层次查询有三个重要的伪列:

LEVEL

用于返回层次查询的层次

CONNECT_BY_ISLEAF

用于返回层次查询当前记录是否到达叶子节点

CONNECT_BY_ISCYCLE

用于返回层次查询的当前记录是否导致层次查询形成环

层次查询有两个重要的关键字:

PRIOR

用于返回层次查询当前节点的父节点。

CONNECT_BY_ROOT

用于返回层次查询当前的根节点。

层次查询一个重要的函数:

SYS_CONNECT_BY_PATH

用于返回指定的列在在层次树中的路径

神通数据库层次查询中环的处理:

层次查询中,有可能因数据错误或者需要形成环数据,但还必须进行层次查询, 这时候必须对环进行合理的处理才能使的层次查询继续。 环有时候很复杂,ORACLE在处理环的时候也有一些缺陷导致其存在死循环的输出, 所以神通数据库定制了自己的环处理方案,那就是在形成环的地方将环打开, 只是将当前行的CONNECT_BY_ISCYCLE参数设置为TRUE继续以后的查询。

语法:

level ::=

参数:

一个重要的伪列LEVEL,它只在层次查询中有效。

层次查询返回的每一行,要么是根,要么是根的儿子或者是儿子的子孙。层次数据就像一棵倒立的树(层次树),根的那一行也是这个树中层次最高的,根是由START WITH指定的。在默认情况下,每一条数据都是根。层次查询还应该由CONNECT BY指明层次数据之间的关系。START WITH和CONNECT BY在后面都有详细的说明,这里就不再叙述。下图显示了层次树的LEVEL值:

../../../../_images/image319.png

LEVEL是一个伪列,这个列在层次查询中才能产生,所以在层次查询之前就不能使用该伪列,

注解

LEVEL不能出现在ORDER SIBLINGS BY中。

注释:

层次查询实现的功能有:

  • 支持CONNECT BY [NOCYCLE]子句
  • 支持START WITH子句
  • 支持PRIOR关键字
  • 支持CONNECT_BY_ROOT关键字
  • 支持ORDER SIBLINGS BY子句
  • 支持SYS_CONNECT_BY_PATH函数
  • 支持LEVEL,CONNECT_BY_ISCYCLE和CONNECT_BY_ISLEAF伪列
  • 支持大数据量的处理,这里的大数据量是指其数据建立的hash表能在内存中装下,而其数据远远超出内存范围。

限制条件:

内存大小必须能够装下Hash表结构以及为每个父结点保留一个儿子,主要是为了性能

层次查询中如果存在环,则处理方式和ORACLE完全不同,所以你不能参照ORACLE的结果, 这主要是因为如果按照ORACLE的方式处理环,完全可能产生死循环的输出。

参见下面的SELECT语句的示例。

示例:

使用层次查询的例子

层次查询的表模式(如果不做特殊说明,以后使用的表的模式都与下面相同):

DROP TABLE EMPLOYEES;

CREATE TABLE EMPLOYEES (employee_id int,last_name char(10), manager_id int);

insert into EMPLOYEES values(101,'Kochhar',100);
insert into EMPLOYEES values(108,'Greenberg',101);
insert into EMPLOYEES values(113,'Popp',108);
insert into EMPLOYEES values(200,'Whalen',101);
insert into EMPLOYEES values(109,'Faviet',108);
insert into EMPLOYEES values(110,'Chen',108);
insert into EMPLOYEES values(111,'Sciarra',108);
insert into EMPLOYEES values(112,'Urman',108);

表中数据如下所示:

SELECT * FROM EMPLOYEES;
../../../../_images/image417.png

查询语句如下:

SELECT employee_id, last_name, manager_id, level,
       sys_connect_by_path (last_name,'/')
from EMPLOYEES
    START WITH last_name = 'Kochhar'
    CONNECT BY PRIOR employee_id = manager_id
    ORDER SIBLINGS BY last_name;

查询结果如下:

../../../../_images/image518.png