热门标签 | HotTags
当前位置:  开发笔记 > 开发工具 > 正文

OracleDatabase10g中新的CONNECTBY特性

这篇文章详细说明了OracleDatabase10g中三个新的CONNECTBY特性。这些示例使用的表和数据与我之前的文章中所用的表和数据相

这篇文章详细说明了 Oracle Database 10g 中三个新的 CONNECT BY 特性。这些示例使用的表和数据与我之前的文章中所用的表和数据相

Jonathan Gennick自 2001 年以来一直是 OTN 会员

Oracle Database 10g 增强了对查询层次或树状结构数据的支持

最近,我在 OTN 写了一篇文章,名为《查询层次结构:最出色的支持》,其中论述了 Oracle 对层次查询的支持。在写那篇文章时,我了解到 Oracle Database 10g 中一些激动人心的新特性,这些特性加强了 Oracle 已有的对查询树状结构数据的稳健支持。 不幸的是,我不能提及那些新特性,因为它们仍在测试中。 其后,我一直迫不及待地等待着该产品发布,现在我终于可以畅所欲言了。

这篇文章详细说明了 Oracle Database 10g 中三个新的 CONNECT BY 特性。这些示例使用的表和数据与我之前的文章中所用的表和数据相同。您可能希望读那篇文章来重温一下 CONNECT BY 查询的工作方式。

问题的起源

如果您阅读了我先前的文章,则您已经了解了如何在层次查询中使用 PRIOR 操作符来从一个父行返回列数据。能够返回到根行有时是很方便的。Oracle Database 10g 中新增的 CONNECT_BY_ROOT 操作符使您能够从一个层次结构中的任何位置引用根行的值。

CONNECT_BY_ROOT 的一个用途是用来识别所有包含了一个给定部分的产品。设想您为一个制造公司工作。您发现 1019 号部件有缺陷,消费品安全委员会命令您收回已售出的所有包含了该部件的产品。您的第一个任务是确定您担心的是哪些产品。您可以通过发出以下查询来开始,作为第一步工作:

SELECT assembly_id, assembly_name FROM bill_of_materials WHERE part_number = 1019 START WITH parent_assembly IS NULL CONNECT BY parent_assembly = PRIOR assembly_id; ASSEMBLY_ID ASSEMBLY_NAME ----------- ----------------------- 141 Lock 144 Lock

这些结果看起来似乎是合理的,但它们存在一个问题。1019 号部件是一个锁,但事实上它被用在两个锁组件中。然而,那些锁组件随后被用在左边和右边的门组件内,门组件随后又被用在一个车身组件中,车身组件最后被用来制造一辆汽车,而我们售出的和要关心的是汽车。您不想要 1019 号部件的直接父组件;您想要 1019 号部件最终的父亲。幸运的是,您的数据库刚刚升级到 Oracle Database 10g,因此您可以利用新的 CONNECT_BY_ROOT 操作符:

SELECT DISTINCT CONNECT_BY_ROOT assembly_id, CONNECT_BY_ROOT assembly_name FROM bill_of_materials WHERE part_number = 1019 START WITH parent_assembly IS NULL CONNECT BY parent_assembly = PRIOR assembly_id; CONNECT_BY_ROOTASSEMBLY_ID CONNECT_BY_ROOTASSEMBLY -------------------------- ----------------------- 100 Automobile

该查询大部分和以前相同。只有两点区别:使用了DISTINCT;在 SELECT 列表中的每一个列名前面出现了 CONNECT_BY_ROOT。CONNECT_BY_ROOT 操作符输出我们关心的那个部件的最终父组件 ID 和名称。DISTINCT 关键字防止一个产品在多个组件中包含了相同部件时被多次列出。因此,结果是您的汽车在它的右边和左边的门里都包含了锁。

寻根究底

层次数据常常是深层嵌套的。考虑这样一个问题:为机械师提供一辆汽车中的组件和部件的一个嵌套列表。汽车包含大量的部件。机械师很少希望立刻了解所有组件和部件的详情。那样的一个列表不仅将使人不知所措,而且当用户只需要该数据的一部分时,,从数据库检索那样一个组件和部件的完整列表以及跨网络传递那样的信息也是非常低效的。相反,您可能选择一开始仅提供顶层的组件,然后让用户从那里开始深入到层次结构内部。例如,您可能一开始提供给我们的用户下列查询的结果:

SELECT ASSEMBLY_ID, RPAD(' ', 2*(LEVEL-1)) || assembly_name assembly_name, quantity FROM bill_of_materials WHERE LEVEL <= 2 START WITH assembly_id = 100 CONNECT BY parent_assembly = PRIOR assembly_id; ASSEMBLY_ID ASSEMBLY_NAME QUANTITY ----------- ------------- ---------- 100 Automobile 110 Combustion Engine 1 120 Body 1 130 Interior 1

通过查看第一级的组件,我们的用户现在能够确定他们是否要进一步向下查看。当有更多的数据要查看时,可以通过将组件名实现为 Web 链接来实现向下查看,或者您可以像 Windows 应用中常见的那样实现一个树状控制。且慢!您怎么知道什么时候一个组件会有更多的数据?什么时候向下查看是可能的?当用户试图从该层次结构的底部向下查看时,您可以让他们试着向下查看到任何组件中,然后给他们一条“没有更多数据”的消息,但这是一种生硬的解决办法,无疑将使他们感到灰心。最好能够提前了解向下查看是否可能。Oracle Database 10g 使我们能够通过 CONNECT_BY_ISLEAF 虚拟列来达到这一目的。您可以使用以下查询来开始:

SELECT ASSEMBLY_ID, RPAD(' ', 2*(LEVEL-1)) || assembly_name assembly_name, quantity, CONNECT_BY_ISLEAF FROM bill_of_materials WHERE LEVEL <= 2 START WITH assembly_id = 100 CONNECT BY parent_assembly = PRIOR assembly_id; ASSEMBLY_ID ASSEMBLY_NAME QUANTITY CONNECT_BY_ISLEAF ----------- ----------------------- ---------- ----------------- 100 Automobile 0 110 Combustion Engine 1 0 120 Body 1 0 130 Interior 1 0

CONNECT_BY_ISLEAF 返回的零指示在该列表中显示的组件中没有一个是叶节点。换句话说,向下查看到它们的任何一个中都是无效的。假定用户向下查看到 Combustion Engine 中。那么您可以发出以下查询来获取组成发动机的子组件:

SELECT ASSEMBLY_ID, RPAD(' ', 2*(LEVEL-1)) || assembly_name assembly_name, quantity, CONNECT_BY_ISLEAF FROM bill_of_materials WHERE LEVEL = 2 START WITH assembly_id = 110 CONNECT BY parent_assembly = PRIOR assembly_id; ASSEMBLY_ID ASSEMBLY_NAME QUANTITY CONNECT_BY_ISLEAF ----------- ----------------------- ---------- ----------------- 111 Piston 6 1 112 Air Filter 1 1 113 Spark Plug 6 1 114 Block 1 1 115 Starter System 1 0

该查询和以前几乎是相同的。Combustion Engine 的 START WITH 组件 ID 值变为 110,该查询特别请求 LEVEL = 2。在这个节点上,您不需要 LEVEL = 1,因为那将再次返回 Combustion Engine 的行,而您已经得到那一行了。

这次,您看到 CONNECT_BY_ISLEAF 有两个值。Piston、Air Filter、Spark Plug 和 Block 的值为 1 指示那些组件是叶节点,且其下没有发现更多的组件。了解到这一点,您就可以调整我们的显示内容,这样用户就知道不用徒劳地在那些组件上向下钻取。另一方面,Starter System 的 CONNECT_BY_ISLEAF 值为 0,这指示仍然存在要检索的子组件。

跳出循环

只要您利用层次数据进行工作,您就可能遇到一个循环的层次。比如说,有人可能将一辆汽车的父组件设为一个火花塞:

UPDATE bill_of_materials SET parent_assembly = 113 WHERE assembly_id=100;

尝试在该组件树中查询 "Automobile" 现在就将失败:

SELECT RPAD(' ', 2*(LEVEL-1)) || assembly_name assembly_name, quantity FROM bill_of_materials START WITH assembly_id = 100 CONNECT BY parent_assembly = PRIOR assembly_id; ERROR: ORA-01436:CONNECT BY loop in user data

当您获得像这样的一条错误消息时,您可以使用 CONNECT_BY_ISCYCLE 虚拟列来确定引起问题的行的位置。要做到这一点,您还必须添加 NOCYCLE 关键字到 CONNECT BY 子句中,防止数据库进入层次结构中的任何循环:

推荐阅读
  • 随着Linux操作系统的广泛使用,确保用户账户及系统安全变得尤为重要。用户密码的复杂性直接关系到系统的整体安全性。本文将详细介绍如何在CentOS服务器上自定义密码规则,以增强系统的安全性。 ... [详细]
  • 服务器虚拟化存储设计,完美规划储存与资源,部署高性能虚拟化桌面
    规划部署虚拟桌面环境前,必须先估算目前所使用实体桌面环境的工作负载与IOPS性能,并慎选储存设备。唯有谨慎估算贴近实际的IOPS性能,才能 ... [详细]
  • 吴石访谈:腾讯安全科恩实验室如何引领物联网安全研究
    腾讯安全科恩实验室曾两次成功破解特斯拉自动驾驶系统,并远程控制汽车,展示了其在汽车安全领域的强大实力。近日,该实验室负责人吴石接受了InfoQ的专访,详细介绍了团队未来的重点方向——物联网安全。 ... [详细]
  • 解决Win10 1709版本文件共享安全警告问题
    每当Windows 10发布新版本时,由于兼容性问题往往会出现各种故障。近期,一些用户在升级至1709版本后遇到了无法访问共享文件夹的问题,系统提示‘文件共享不安全,无法连接’。本文将提供多种解决方案,帮助您轻松解决这一难题。 ... [详细]
  • 在测试软件或进行系统维护时,有时会遇到电脑蓝屏的情况,即便使用了沙盒环境也无法完全避免。本文将详细介绍常见的蓝屏错误代码及其解决方案,帮助用户快速定位并解决问题。 ... [详细]
  • 在日常生活中,支付宝已成为不可或缺的支付工具之一。本文将详细介绍如何通过支付宝实现免费提现,帮助用户更好地管理个人财务,避免不必要的手续费支出。 ... [详细]
  • 调试利器SSH隧道
    在开发微信公众号或小程序的时候,由于微信平台规则的限制,部分接口需要通过线上域名才能正常访问。但我们一般都会在本地开发,因为这能快速的看到 ... [详细]
  • 龙蜥社区开发者访谈:技术生涯的三次蜕变 | 第3期
    龙蜥社区的开发者们通过自己的实践和经验,推动着开源技术的发展。本期「龙蜥开发者说」聚焦于一位资深开发者的三次技术转型,分享他在龙蜥社区的成长故事。 ... [详细]
  • Spark中使用map或flatMap将DataSet[A]转换为DataSet[B]时Schema变为Binary的问题及解决方案
    本文探讨了在使用Spark的map或flatMap算子将一个数据集转换为另一个数据集时,遇到的Schema变为Binary的问题,并提供了详细的解决方案。 ... [详细]
  • 如何安装FARO Scene 2018?详尽的永久授权指南
    FARO Scene 2018 是一款专为专业用户设计的3D点云处理与管理软件。该软件支持从高精度3D激光扫描设备获取的大规模3D扫描数据的查看、管理和处理。本文将详细介绍如何安装及激活FARO Scene 2018的永久许可。 ... [详细]
  • Centos7 Tomcat9 安装笔记
    centos7,tom ... [详细]
  • 本文详细介绍了 Spark 中的弹性分布式数据集(RDD)及其常见的操作方法,包括 union、intersection、cartesian、subtract、join、cogroup 等转换操作,以及 count、collect、reduce、take、foreach、first、saveAsTextFile 等行动操作。 ... [详细]
  • Spark与HBase结合处理大规模流量数据结构设计
    本文将详细介绍如何利用Spark和HBase进行大规模流量数据的分析与处理,包括数据结构的设计和优化方法。 ... [详细]
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • 本文对比了杜甫《喜晴》的两种英文翻译版本:a. Pleased with Sunny Weather 和 b. Rejoicing in Clearing Weather。a 版由 alexcwlin 翻译并经 Adam Lam 编辑,b 版则由哈佛大学的宇文所安教授 (Prof. Stephen Owen) 翻译。 ... [详细]
author-avatar
文帅zssw
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有