T-SQL XML查询过滤器节点数据

时间:2018-03-13 18:57:21

标签: sql xml tsql xquery

我已将相当大的Xml数据存储到二进制字段中。并希望提取最少的信息,因为它与其他表有关系。

截断的xml数据的示例:

<CIVersion xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/EM.FactoryEntities" z:Id="i1">
  <CSettings xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" z:Id="i2">
    <d2p1:Name>V_TM</d2p1:Name>
  </CSettings>
  <ComponentModel xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" z:Id="i4">
    <Id xmlns="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities">0</Id>
    <d2p1:Components>
      <d2p1:CellComponent z:Id="i5">
        <d2p1:Children>
          <d2p1:CellComponent z:Id="i6">
            <d2p1:Children />
            <d2p1:Equipment xmlns:d7p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.CIs" z:Id="i7" i:type="d7p1:SConConfiguration">
              <d2p1:RequiredNode z:Id="i9">
                <Name>TM</Name>
                <Version>v1.0.0</Version>
              </d2p1:RequiredNode>
              <d2p1:Name>EqConnection</d2p1:Name>
            </d2p1:Equipment>
            <d2p1:EquipmentObjectType i:nil="true" />
            <d2p1:Name>JobFactory</d2p1:Name>
            <d2p1:Parameters />
          </d2p1:CellComponent>
          <d2p1:CellComponent z:Id="i14">
            <d2p1:Children />
            <d2p1:Equipment z:Ref="i7" />
            <d2p1:EquipmentObjectType>Loadport</d2p1:EquipmentObjectType>
            <d2p1:Name>P2</d2p1:Name>
            <d2p1:Parameters>
              <d2p1:ComponentParameter z:Id="i15">
              </d2p1:ComponentParameter>
            </d2p1:Parameters>
            <d2p1:Type>Interfaces.IPort</d2p1:Type>
          </d2p1:CellComponent>
          <d2p1:CellComponent z:Id="i36">
            <d2p1:Children />
            <d2p1:Equipment xmlns:d7p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.CIs" z:Id="i7" i:type="d7p1:SConConfiguration">
              <d2p1:RequiredNode z:Id="i8">
                <Name>TFF</Name>
                <Version>v1.0.2</Version>
              </d2p1:RequiredNode>
              <d2p1:Name>EqConnection2</d2p1:Name>
            </d2p1:Equipment>
            <d2p1:EquipmentObjectType i:nil="true" />
            <d2p1:Name>Synchronizer</d2p1:Name>
            <d2p1:Parameters />
          </d2p1:CellComponent>
        </d2p1:Children>
        <d2p1:Equipment z:Ref="i7" />
        <d2p1:EquipmentObjectType>Equipment</d2p1:EquipmentObjectType>
        <d2p1:Name>V_TM</d2p1:Name>
      </d2p1:CellComponent>
    </d2p1:Components>
  </ComponentModel>
    <Name>Virt_TM</Name>
</CIVersion>

我只需要为&#39; d2p1提取多个值:RequiredNode&#39;节点。所以上面的例子返回:

<RequiredNodes>
  <d2p1:RequiredNode z:Id="i9">
    <Name>TM</Name>
    <Version>v1.0.0</Version>
  </d2p1:RequiredNode>
  <:RequiredNode z:Id="i9">
    <Name>TFF</Name>
    <Version>v1.0.2</Version>
  </d2p1:RequiredNode>
</RequiredNodes>

此行返回CSettings值:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/EM.FactoryEntities', 
        'http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs' as "d2p1")

SELECT TOP 1000 [ID],
    Convert(Xml,[CONFIGURATION]).query('/CIVersion/CSettings') AS CSettings
  FROM [TABLE_NAME]

我需要正确地为Oracle和MsSQL工作的相同查询。

1 个答案:

答案 0 :(得分:1)

在SQL Server中,您可以执行以下操作:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/EM.FactoryEntities', 
        'http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs' as "d2p1")

SELECT CAST('<RequiredNode>'+CAST(nd.query('.') as varchar(8000)) +'</RequiredNode>'AS xml)
FROM [TABLE_NAME]
CROSS APPLY [TABLE_NAME].[CONFIGURATION].nodes('//d2p1:RequiredNode') results(nd);

此查询不会从 name version 中删除名称空间,但这不应该太难。这是我用来测试它的代码。请注意,我将缺少的命名空间添加到您的XML中。

IF object_id('tempdb..#x') IS NOT NULL DROP TABLE #x;
CREATE TABLE #x (id int identity, xmldata xml);

INSERT #x (xmldata) VALUES 
('<CIVersion xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/EM.FactoryEntities" z:Id="i1">
  <CSettings xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" z:Id="i2">
    <d2p1:Name>V_TM</d2p1:Name>
  </CSettings>
  <ComponentModel xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" z:Id="i4">
    <Id xmlns="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities">0</Id>
    <d2p1:Components>
      <d2p1:CellComponent z:Id="i5">
        <d2p1:Children>
          <d2p1:CellComponent z:Id="i6">
            <d2p1:Children />
            <d2p1:Equipment xmlns:d7p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.CIs" z:Id="i7" i:type="d7p1:SConConfiguration">
              <d2p1:RequiredNode z:Id="i9">
                <Name>TM</Name>
                <Version>v1.0.0</Version>
              </d2p1:RequiredNode>
              <d2p1:Name>EqConnection</d2p1:Name>
            </d2p1:Equipment>
            <d2p1:EquipmentObjectType i:nil="true" />
            <d2p1:Name>JobFactory</d2p1:Name>
            <d2p1:Parameters />
          </d2p1:CellComponent>
          <d2p1:CellComponent z:Id="i14">
            <d2p1:Children />
            <d2p1:Equipment z:Ref="i7" />
            <d2p1:EquipmentObjectType>Loadport</d2p1:EquipmentObjectType>
            <d2p1:Name>P2</d2p1:Name>
            <d2p1:Parameters>
              <d2p1:ComponentParameter z:Id="i15">
              </d2p1:ComponentParameter>
            </d2p1:Parameters>
            <d2p1:Type>Interfaces.IPort</d2p1:Type>
          </d2p1:CellComponent>
          <d2p1:CellComponent z:Id="i36">
            <d2p1:Children />
            <d2p1:Equipment xmlns:d7p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.CIs" z:Id="i7" i:type="d7p1:SConConfiguration">
              <d2p1:RequiredNode z:Id="i9">
                <Name>TFF</Name>
                <Version>v1.0.2</Version>
              </d2p1:RequiredNode>
              <d2p1:Name>EqConnection2</d2p1:Name>
            </d2p1:Equipment>
            <d2p1:EquipmentObjectType i:nil="true" />
            <d2p1:Name>Synchronizer</d2p1:Name>
            <d2p1:Parameters />
          </d2p1:CellComponent>
        </d2p1:Children>
        <d2p1:Equipment z:Ref="i7" />
        <d2p1:EquipmentObjectType>Equipment</d2p1:EquipmentObjectType>
        <d2p1:Name>V_TM</d2p1:Name>
      </d2p1:CellComponent>
    </d2p1:Components>
  </ComponentModel>
    <Name>Virt_TM</Name>
</CIVersion>');

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/EM.FactoryEntities', 
        'http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs' as "d2p1")

SELECT 
  RequiredNode = CAST('<RequiredNode>'+CAST(nd.query('.') as varchar(8000)) +'</RequiredNode>'AS xml),
  [Name]       = nd.value('(*:Name)[1]', 'varchar(8000)'),
  [Version]    = nd.value('(*:Version)[1]', 'varchar(8000)')
FROM #x
CROSS APPLY xmldata.nodes('//d2p1:RequiredNode') results(nd);

<强>结果:

<RequiredNode>
  <d2p1:RequiredNode xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" xmlns:p1="http://schemas.microsoft.com/2003/10/Serialization/" p1:Id="i9">
    <p2:Name xmlns:p2="http://schemas.datacontract.org/2004/07/EM.FactoryEntities">TM</p2:Name>
    <p3:Version xmlns:p3="http://schemas.datacontract.org/2004/07/EM.FactoryEntities">v1.0.0</p3:Version>
  </d2p1:RequiredNode>
</RequiredNode>
<RequiredNode>
  <d2p1:RequiredNode xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" xmlns:p1="http://schemas.microsoft.com/2003/10/Serialization/" p1:Id="i9">
    <p2:Name xmlns:p2="http://schemas.datacontract.org/2004/07/EM.FactoryEntities">TFF</p2:Name>
    <p3:Version xmlns:p3="http://schemas.datacontract.org/2004/07/EM.FactoryEntities">v1.0.2</p3:Version>
  </d2p1:RequiredNode>
</RequiredNode>