创建一个查询,使用过滤器更快地以 XML 格式获取数据

Posted

技术标签:

【中文标题】创建一个查询,使用过滤器更快地以 XML 格式获取数据【英文标题】:create a query that fetch data as XML more faster with filters 【发布时间】:2020-11-26 21:45:49 【问题描述】:

我正在使用 SQL Server 2014,试图以分层结构从 SQL Server 获取 xml, `

WITH
parent as (select ModelId,ParentIdFK,ModelName,Expanded,SortOrder from model where NodeLevel =  0),
FirstNode as (select ModelId,ParentIdFK,ModelName,Expanded,SortOrder from model where ParentIdFK in(select ModelId from parent)),
SecondNode as (select ModelId,ParentIdFK,ModelName,Expanded,SortOrder from model where ParentIdFK in(select ModelId from FirstNode)),
ThirdNode as (select ModelId,ParentIdFK,ModelName,Expanded,SortOrder from model where ParentIdFK in(select ModelId from SecondNode)),
FouthNode as (select ModelId,ParentIdFK,ModelName,Expanded,SortOrder from model where ParentIdFK in(select ModelId from ThirdNode)),
FifthNode as (select ModelId,ParentIdFK,ModelName,Expanded,SortOrder from model where ParentIdFK in(select ModelId from FouthNode)),
SixthNode as (select ModelId,ParentIdFK,ModelName,Expanded,SortOrder from model where ParentIdFK in(select ModelId from FifthNode)),
XmlData as (select (select p.*,L1.*,L2.*,L3.*,L4.*,L5.*,L6.* from parent p
left join FirstNode L1 on  L1.ParentIdFK =p.ModelId 
left join SecondNode L2 on L2.ParentIdFK=L1.ModelId
left join ThirdNode L3 on L3.ParentIdFK=L2.ModelId
left join FouthNode L4 on L4.ParentIdFK=L3.ModelId
left join FifthNode L5 on L5.ParentIdFK=L4.ModelId
left join SixthNode L6 on L6.ParentIdFK=L5.ModelId
for xml auto , ROOT('ModelLines'),type) as XMLDataModel) 
(select @data = XMLDataModel from XmlData)

`

我得到了输出

  <model ModelId="11" ParentIdFK="3" ModelName="Sedans" Expanded="0" SortOrder="1">
      <model ModelId="14" ParentIdFK="11" ModelName="328i Sedan" Expanded="0" SortOrder="1">
        <model>
          <model />
        </model>
      </model>
      <model ModelId="15" ParentIdFK="11" ModelName="328xi Sedan" Expanded="0" SortOrder="2">
        <model>
          <model />
        </model>
      </model>
      <model ModelId="16" ParentIdFK="11" ModelName="335i Sedan" Expanded="0" SortOrder="3">
        <model>
          <model />
        </model>
      </model>
      <model ModelId="167" ParentIdFK="11" ModelName="Sheilas Model" Expanded="0" SortOrder="3">
        <model>
          <model />
        </model>
      </model>
      <model ModelId="289" ParentIdFK="11" ModelName="335xi Sedan" Expanded="0" SortOrder="3">
        <model>
          <model />
        </model>
      </model>
    </model>
    <model ModelId="12" ParentIdFK="3" ModelName="Sports Wagon" Expanded="0" SortOrder="2">
      <model ModelId="17" ParentIdFK="12" ModelName="328xi Sports Wagon" Expanded="0" SortOrder="1">
        <model>
          <model />
        </model>
      </model>
      <model ModelId="18" ParentIdFK="12" ModelName="328i Sports Wagon" Expanded="0" SortOrder="2">
        <model>
          <model />
        </model>
      </model>
      <model ModelId="214" ParentIdFK="12" ModelName="Convertible" Expanded="0" SortOrder="4">
        <model ModelId="223" ParentIdFK="214" ModelName="328i Convertible" Expanded="0" SortOrder="1">
          <model />
        </model>
        <model ModelId="224" ParentIdFK="214" ModelName="335i Convertible" Expanded="0" SortOrder="3">
          <model />
        </model>
      </model>
    </model>

这个查询也是2s,但是有很多没有属性的节点

所以我尝试set @data.modify('delete //model[empty(@ModelId)]') 删除这些节点 这需要将近 30 秒。任何人都可以建议一种更快更好的方法来更快地获取 xmal

【问题讨论】:

to remove these nodes this takes nearly 30s 那么您是否在问是否有更快的方法来删除节点或在没有不需要节点的情况下获取 xml?在我看来,你想要完成什么并不是很清楚。对于您正在做的事情,modify 是正确的,这个method 采用 XML DML 语句从 XML 数据中插入、更新或删除节点,您认为可以加快速度吗?同样,恕我直言,需要更改查询以排除您不需要的节点。 (续)那你根本不需要modify 方法,只需要得到你需要的。 在提出问题时,您需要提供一个可重现的最小示例。请参考以下链接:***.com/help/minimal-reproducible-example 请提供以下内容: (1) DDL 和样本数据填充,即 CREATE table(s) 加上 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试实现它。 (3) 期望的输出,基于上面#1 中的样本数据。 (4) 你的 SQL Server 版本 (SELECT @@version;) 某人在某处知道 SQL XML 查询足以回答,但大多数人看到这样的查询并逃跑(太复杂、脆弱且难以支持)。我的方法是只编写一个简单的 SQL 查询,只获取您需要的数据,然后使用 XSL/XML Linq 或类似工具对其进行整形。希望对您有所帮助。 【参考方案1】:

使用 xml linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication164

    class Program
    
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        
            XDocument doc = XDocument.Load(FILENAME);

            XElement[] models = doc.Descendants("model").ToArray();

            for (int i = models.Count() - 1; i >= 0; i--)
            
                if (models[i].Attributes().Count() == 0)
                
                    models[i].Remove();
                
            

 
        
    
 

【讨论】:

这如何解决 sql 中的问题?这个解决方案如何更快、更相关? 发布的代码是c#,那么SQL与问题有什么关系? xml 字符串正在 c# 中处理。 OP 在 sql 中使用 XML,因此是 (for xml auto),而不是 c#... 你是说上面的op查询不是sql查询?

以上是关于创建一个查询,使用过滤器更快地以 XML 格式获取数据的主要内容,如果未能解决你的问题,请参考以下文章

使用变量过滤器更快地进行 PostgreSQL 查询

更快地获取查询

PHP:JSON 或 XML 解析器更快吗?

过滤 SQL 查询

使用存储过程从视图中检索或过滤数据是不是比使用存储过程从表中获取或过滤数据更快?

在 Access DB 中查询比使用 Excel(电源查询编辑器)的外部查询更快?