当前位置: 首页 > 面试题库 >

使用nodes()方法展平SQL中的分层XML

危烨煜
2023-03-14
问题内容

我有一个存储过程,该存储过程将XML文档作为参数,其结构类似于以下内容:

<grandparent name="grandpa bob">
  <parent name="papa john">
    <children>
      <child name="mark" />
      <child name="cindy" />
    </children>
  </parent>
  <parent name="papa henry">
    <children>
      <child name="mary" />
    </children>
  </parent>
</grandparent>

我的要求是“展平”此数据,以便可以将其插入临时表中并在该过程中进行进一步的操作,因此上述XML变为:

Grandparent Name Parent Name     Child Name
---------------- --------------- ---------------
grandpa bob      papa john       mark
grandpa bob      papa john       cindy
grandpa bob      papa henry      mary

当前,这是使用SQL Server XML节点完成的:

SELECT
    VIRT.node.value('../../../@name','varchar(15)') 'Grandparent Name',
    VIRT.node.value('../../@name','varchar(15)') 'Parent Name',
    VIRT.node.value('@name','varchar(15)') 'Child Name'
FROM
    @xmlFamilyTree.nodes('/grandparent/parent/children/child') AS VIRT(node)

直到我开始在该过程中抛出大量数据(即1000个以上的child节点)时,此方法才有效,这时该过程停止了,并需要1至2分钟的时间来执行。我认为这可能是由于我从最低级别(<child)开始,然后每次出现时都遍历XML文档。将单个查询分成3个块(每个节点我需要数据)会提高此处的性能吗?鉴于这些节点上都没有可用于加入备份的“键”,任何人都可以提供任何指针来说明如何执行此操作吗?


问题答案:

在网上浏览了一下之后,我似乎已经回答了自己的问题:

SELECT
    grandparent.gname.value('@name', 'VARCHAR(15)'),
    parent.pname.value('@name', 'VARCHAR(15)'),
    child.cname.value('@name', 'VARCHAR(15)')
FROM
    @xmlFamilyTree.nodes('/grandparent') AS grandparent(gname)
CROSS APPLY
    grandparent.gname.nodes('*') AS parent(pname)
CROSS APPLY
    parent.pname.nodes('children/*') AS child(cname)

使用CROSS APPLYI可以选择顶级grandparent节点,然后使用它来选择子parent节点,依此类推。使用这种html" target="_blank">方法,我的查询从大约
1分钟30秒的 执行 时间 减少到大约 6秒

但是,有趣的是,如果我使用“旧”OPEN XML方法检索相同的数据,则查询将在 1秒内 执行!

似乎您可能必须根据传入的文档的预期大小/复杂性,逐案处理这两种技术。



 类似资料:
  • 问题内容: 我正在努力提高性能,以证明我已经写过并且没有运气的概念证明。我认为这种方法可能有缺陷,但是我正在努力寻找另一种解决方案。我介绍了我可以找到的所有Ask Tom文章和论坛帖子。 我们正在运行Oracle 10g R2。 我们将项目按层次结构排列。数量是在关系上定义的。层次结构中有两种类型的对象:逻辑分组的程序集和代表实际项目的项目。因此,如果我们要代表一个完整的工具集,我们将有一个代表整

  • 问题内容: 我有一堆这样的表: 但是我需要一个扁平化的版本,像这样: 我不知道如何执行此操作,我能想到的最好的办法是编写一个临时表,定义所有122列,然后执行并遍历> _ < 只为一个表编写此查询不是最好的方法,但是我需要像这样为另外三十个相同大小的表展平数据。嗯…有什么建议吗? 我也很想知道我在做什么是否是一件普通的事情…? 我需要对统计软件的SQL数据进行归一化/展平。 问题答案: 您所需要的

  • 我需要用我的代码打开一个视频文件,它在Eclipse中运行得非常好,但是当我导出到一个可运行的JAR中时,我会得到一个错误“URI不分层”。 我见过有人建议使用getResourceAsStream(),但我在使用桌面时需要一个文件对象。getDesktop。打开(文件)。有人能帮我吗? 以下是代码: 如果有帮助,我的文件夹列表如下 > src 视频 编辑:我计划只在windows上运行,并使用l

  • 问题内容: 我有一个基本的实体树结构。该树最多可以有5个节点深,但可以有N个节点宽。我已将这种关系映射到类似于以下所示的表中: 我从一个已知的对象开始,这可以转换为具有起始的“ myID”。现在,我想获取所有子节点。有没有一种方法可以在一条语句中获得所有子节点?这需要包括我的孩子们的孩子,然后沿着树走下去。我正在使用Oracle SQL。 谢谢,周杰伦 问题答案:

  • 本文向大家介绍在JavaScript中使用开平方根的sqrt()方法,包括了在JavaScript中使用开平方根的sqrt()方法的使用技巧和注意事项,需要的朋友参考一下  这个方法返回一个数的平方根。如果数的值是负的,开方返回NaN。 语法 下面是参数的详细信息:     x: 一个数字 返回值: 返回一个数字的正弦值。 例子: 这将产生以下结果:

  • 问题内容: 我有一个包含层次结构数据的表。目前,在此层次结构中大约有8个级别。 我真的很喜欢数据的结构方式,但是当我需要知道第8级记录是否是第1级记录的子级时,性能令人沮丧。 我有PL / SQL存储的函数,这些函数为我执行这些查找,每个函数都有一条语句。当我查询少量记录时,这种方法很好用,但是现在我需要一次查询约1万条记录,并且每个记录都运行此功能。我需要2-3分钟才能在几秒钟内运行它。 根据我