在上一篇文章中我说明了如何分类层次化查询中的输入项但是要使一个层次化查询得以运行就不能使数据返回到自身也就是说一个母行不能把自己或它的一个子行作为自己的母行如果发生这种情况Oracle将重复不断地执行这个链接永远无法到达一个确定的终点
幸运的是Oracle对这种情况进行测试并用以下错误信息中止查询
ORA: CONNECT BY loop in user data
过去我们很难发现一个大型数据集中的所有行彼此引用因为查询在发现第一个循环时就已经终止在Oracle g中SELECT语句的两个新语法元素为你提供了解决这类数据错误的工具NOCYCLE和CONNECT_BY_ISCYCLE
CONNECT BY子句中增加的NOCYCLE参数指出即使探查到一个循环Oracle无论如何也要返回一个行这为查明哪个行出错提供了极有价值的线索(不用担心——Oracle会停止评估循环转向下一行)如果当前的行包含一个循环CONNECT_BY_ISCYCLE伪列将返回否则将返回组合使用这两个元素就能查明需要修复的内容
列表A是和上一篇文章中相同的层次化查询我们根据HR样本方案执行它
这次我们在数据中介绍另一个循环将员工Kochhar()改为向Urman()报告Urman向Greenberg()报告Greenberg则向Kochhar报告从而建立一个循环
UPDATE employees
SET manager_id =
WHERE employee_id = ;
COMMIT;
如果我们重新运行上述查询将得到ORA错误列表B探查我们介绍的错误我们没有使用CONNECT BY PRIOR而是使用了CONNECT BY NOCYCLE PRIOR即使探查到一个循环它仍然会继续进行查询我们还在报告中增加了manager_id列和CONNECT_BY_ISCYCLE伪列以帮助解决这个问题
输出结果在Urman行显示回溯循环链我们就能发现出错的地方Kochhar那一行
column Reports To format a
set pagesize
SELECT LPAD( *(LEVEL))||last_name Reports To employee_id
FROM employees
START WITH employee_id IN ( )
CONNECT BY PRIOR employee_id = manager_id
/
Reports To EMPLOYEE_ID
De Haan
Hunold
Austin
Ernst
Lorentz
Pataballa
Kochhar
Baer
Greenberg
Chen
Faviet
Popp
Sciarra
Urman
Kochhar
ERROR:
ORA: CONNECT BY loop in user data
Bob Watkins(OCPMCDBAMCSEMCT)是一位有年经验的计算机专业人士从事过技术培训师顾问与数据库管理员等职