在布尔条件和在一般的 SQL 表达式中,除了表达式和运算符是有效的之外,在 CONNECT BY 子句中指定的 condition 支持另外两种语法结构,仅在包括层级子句的 SELECT 语句中,PRIOR 运算符和 LEVEL 伪列才是有效的。
CONNECT BY mgrid = PRIOR empid此处,在 mgrid 中指定管理者的那些行满足 CONNECT BY 条件,在先前的迭代中与员工值相匹配的列在 empid 列中。
CONNECT BY PRIOR (salary - 10000) = salary
在同一 CONNECT BY 条件中,可以多次包括 PRIOR 运算符。另请参阅主题 层级查询子句,该主题提供一个在 CONNECT BY 子句的条件中使用 PRIOR 运算符的层级查询的示例。
伪列是与列名称共享同一命名空间的 SQL 的关键字,在某些其中的列表达式为有效的上下文中那是有效的。
LEVEL 是返回在返回了行的层级子句中迭代步骤的序号的伪列。对于由 START WITH 子句返回的所有行,LEVEL 返回值 1。通过应用 CONNECT BY 子句的第一个迭代返回的行返回 2。通过 CONNECT BY 的连续的迭代返回的行有增量为 1 的 LEVEL 值,因此 LEVEL = (N + 1) 表明为第 N 次 CONNECT BY 迭代返回的值。LEVEL 列的数据类型是 INTEGER。
SELECT name, LEVEL FROM employee START WITH name = 'Goyal' CONNECT BY PRIOR empid = mgrid;该查询返回这些结果:
name level Goyal 1 Zander 2 McKeough 3 Barnes 3 Henry 2 O'Neil 3 Smith 3 Shoeman 3 Scott 2 9 row(s) retrieved.
在包括层级子句的 SELECT 语句的 Projection 子句中,以及在 CONNECT BY 子句的 condition 中,可包括 LEVEL。
如果在层级中的下一级该行可能循环,则 CONNECT_BY_ISCYCLE 是返回 1 的伪列。即,该行有一个直接的孩子,该孩子又是在 CONNECT BY 子句中指定的搜索条件给出的祖先。如果该行不直接地导致循环,则该列返回 0。仅当在 CONNECT BY 子句中指定 NOCYCLE 时,才有可能为非 0 的值。此列的数据类型是 INTEGER。
下列 UPDATE 语句在 employee 表的数据层级中创建循环:
UPDATE employee SET mgrid = 5 WHERE empid = 17;
下列层级查询在 Projection 子句中包括 CONNECT_BY_ISCYCLE 伪列,但在它遇到 UPDATE 语句创建的循环的步骤中,CONNECT BY 子句抛出错误。
SELECT empid, name, mgrid, CONNECT_BY_ISLEAF leaf, CONNECT_BY_ISCYCLE cycle FROM employee START WITH name = 'Goyal' CONNECT BY PRIOR empid = mgrid; 665: Internal error on semantics - CONNECT_BY_ISCYCLE is used without NOCYCLE parameter.. Error in line 1 Near character position 72
在它遇到 UPDATE 语句创建的循环的步骤中抛出错误的 CONNECT BY 子句中,通过指定 NOCYCLE,此查询可避免 -655 错误。
SELECT empid, name, mgrid, CONNECT_BY_ISLEAF leaf, CONNECT_BY_ISCYCLE cycle FROM employee START WITH name = 'Goyal' CONNECT BY NOCYCLE PRIOR empid = mgrid;
要获取此查询的结果,请参阅在主题 CONNECT BY 子句 中的对 NOCYCLE 关键字的描述的示例。
如果该行如 CONNECT BY 所定义的那样是层级中的叶子,则 CONNECT_BY_ISLEAF 是返回 1 的伪列。如果节点在查询结果层级中(不是在实际的数据层级中)没有孩子,则该节点是叶节点。如果该行不是叶子,则该列返回 0。该列的数据类型是 INTEGER。
下列层级查询在 Projection 子句中指定 CONNECT_BY_ISLEAF 伪列,并声明 leaf 为那列的别名,在 DB-Access 中的结果集显示为:
SELECT empid, name, mgrid, CONNECT_BY_ISLEAF leaf FROM emp1oyee START WITH name = 'Goyal' CONNECT BY PRIOR empid = mgrid; empid name mgrid leaf 16 Goyal 17 0 14 Scott 16 1 12 Henry 16 0 9 Shoeman 12 1 8 Smith 12 1 7 O'Neil 12 1 11 Zander 16 0 6 Barnes 11 1 5 McKeough 11 1 9 row(s) retrieved.
下列示例中的层级查询从 employee 表返回行,既包括员工要向其直接地报告的管理者的标识编号,也包括位于此查询的层级的根的管理者的名称。
SELECT empid, name, mgrid, CONNECT_BY_ROOT name AS topboss FROM employee START WITH name = 'Goyal' CONNECT BY PRIOR empid = mgrid; empid name mgrid topboss 16 Goyal 17 Goyal 14 Scott 16 Goyal 12 Henry 16 Goyal 9 Shoeman 12 Goyal 8 Smith 12 Goyal 7 O'Neil 12 Goyal 11 Zander 16 Goyal 6 Barnes 11 Goyal 5 McKeough 11 Goyal 9 row(s) retrieved.
在包括层级子句的 SELECT 语句中调用 SYS_CONNECT_BY_PATH ( ) 函数是有效的,但不可从层级子句调用此函数。如果您尝试在 START WITH 或 CONNECT BY 子句的 condition 之内运行此函数,则 GBase 8s 返回错误。
在层级查询中,SYS_CONNECT_BY_PATH 函数可用来构建表示路径的字符串,该路径从对应于根节点的行至当前行。
从 SYS_CONNECT_BY_PATH ( ) 的返回值是 LVARCHAR(4000) 类型。
下列示例中的层级查询调用在 Projection 列表中的 SYS_CONNECT_BY_PATH 函数,以 employee.name 列和斜线(/)字符作为它的参数。
SELECT empid, name, mgrid, SYS_CONNECT_BY_PATH( name,'/') as hierarchy FROM employee START WITH name = 'Henry' CONNECT BY PRIOR empid = mgrid;
该查询返回数据层级的子集之内的行,其中在 START WITH 子句中指定 Henry 作为根,展现每一员工和员工的管理者的名称和 empid 编号,以及在该层级中到 Henry 的路径。CONNECT BY 子句使用相等断言 PRIOR empid = mgrid 来返回向管理者报告的员工(在此情况下,仅 Henry),通过先前的步骤返回了其 empid。该查询的结果集是:
empid 12 name Henry mgrid 16 hierarchy /Henry empid 9 name Shoeman mgrid 12 hierarchy /Henry/Shoeman empid 8 name Smith mgrid 12 hierarchy /Henry/Smith empid 7 name O'Neil mgrid 12 hierarchy /Henry/O'Neil 4 row(s) retrieved.
查询执行结束,展示返回的四行,此处,hierarchy 是 SYS_CONNECT_BY_PATH( name,'/') 为每一行返回到 Henry 的路径的别名。(在第一个返回的行中,字符串 /Henry 展示 Henry 的根状态。)