热门标签 | 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 子句中,防止数据库进入层次结构中的任何循环:

推荐阅读
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 微软小娜企业版发布新版本,提供构建自定义技能的套件
    微软将向企业级市场发布微软小娜企业版的新版本,该版本提供了构建自定义技能的套件,使企业员工可以更方便地使用数字助理。目前该套件仍处于内测期间,只有部分企业可以获得,其他有兴趣的企业需要继续等待。新版本的套件可以帮助员工构建各种自定义技能,如检查休假余额、创建服务凭证等。微软通过让多个开发人员编辑和管理机器人通道注册配置来改善开发者的体验,团队可以自行访问和更改技能注册,满足企业实际需求。微软小娜企业版已经在各个行业得到采用,能够帮助员工专注于优先事项,将非优先处理的任务交给微软小娜处理。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • PDF内容编辑的两种小方法,你知道怎么操作吗?
    本文介绍了两种PDF内容编辑的方法:迅捷PDF编辑器和Adobe Acrobat DC。使用迅捷PDF编辑器,用户可以通过选择需要更改的文字内容并设置字体形式、大小和颜色来编辑PDF文件。而使用Adobe Acrobat DC,则可以通过在软件中点击编辑来编辑PDF文件。PDF文件的编辑可以帮助办公人员进行文件内容的修改和定制。 ... [详细]
  • win10系统搭建Java开发环境的操作方法
    本文介绍了win10系统搭建Java开发环境的详细操作方法,包括下载Windows10系统和Java SE,安装Java开发环境,设置变量等步骤。操作简单,只需按照指导进行即可。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 【Windows】实现微信双开或多开的方法及步骤详解
    本文介绍了在Windows系统下实现微信双开或多开的方法,通过安装微信电脑版、复制微信程序启动路径、修改文本文件为bat文件等步骤,实现同时登录两个或多个微信的效果。相比于使用虚拟机的方法,本方法更简单易行,适用于任何电脑,并且不会消耗过多系统资源。详细步骤和原理解释请参考本文内容。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • macOS10.12安装win10系统教程,实现双系统安装
    本文介绍了如何在macOS10.12系统上安装win10系统,实现双系统的安装。通过使用Boot Camp助理,选取win10系统镜像并分配系统容量,然后进行安装。安装完win10系统后,安装驱动并重启系统即可完成双系统的安装。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • Spark Streaming和Kafka整合之路(最新版本)
    2019独角兽企业重金招聘Python工程师标准最近完成了SparkStreaming和Kafka的整合工作,耗时虽然不长,但是当中还是遇到了不少 ... [详细]
  • 开发笔记:Spark Java API 之 CountVectorizer
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了SparkJavaAPI之CountVectorizer相关的知识,希望对你有一定的参考价值。 ... [详细]
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社区 版权所有