【问题标题】:Querying an XML column - returning relational data查询 XML 列 - 返回关系数据
【发布时间】:2015-10-21 22:59:11
【问题描述】:

我有一个问题,我必须在包含在 XML 列中的 SQL 查询中返回数据。我有一些初步的结果,但很难快速取得进展。到目前为止,我有这个:

XML(以一行为例):

<root>
  <property>
    <Name>Boolean</Name>
    <Value>True</Value>
  </property>
  <property>
    <Name>Integer</Name>
    <Value>0</Value>
  </property>
</root>

SQL:

select ItemID,
       boolean = CASE WHEN CF.exist('/root/property/Name[text() = "Boolean"]') = 1 
        THEN CF.value('(/root/property/Value)[1]', 'varchar(32)') END,
       [integer] = CASE WHEN CF.exist('/root/property/Name[text() = "Integer"]') = 1 
        THEN CF.value('(/root/property/Value)[2]', 'varchar(32)') END
from 
       [TTS].[dbo].[tblInItem]

结果数据是这样的:

您可以看到第 4 行正在填充一个布尔值,其中应该有一个整数。这是因为该行的 XML 是:

<root>
  <property>
    <Name>Boolean</Name>
    <Value>True</Value>
  </property>
  <property>
    <Name>Another Boolean</Name>
    <Value>True</Value>
  </property>
  <property>
    <Name>Integer</Name>
    <Value>0</Value>
  </property>
</root>

那么,如何将CF.value('(/root/property/Value)[2]', 'varchar(32)') 中的单例[2] 替换为返回节点位置的东西?

我也认识到可能有许多更优雅的解决方案,并且对其中任何一个都持开放态度。

【问题讨论】:

    标签: sql-server sql-server-2008 xquery-sql


    【解决方案1】:

    跳过 case 语句,将属性名称的谓词放在获取值的 xPath 表达式中。

    SQL Fiddle

    MS SQL Server 2008 架构设置

    create table T(ItemID int identity primary key, CF xml);
    
    insert into T(CF) values('<root>
      <property>
        <Name>Boolean</Name>
        <Value>True</Value>
      </property>
      <property>
        <Name>Integer</Name>
        <Value>0</Value>
      </property>
    </root>');
    
    insert into T(CF) values('<root>
      <property>
        <Name>Boolean</Name>
        <Value>True</Value>
      </property>
      <property>
        <Name>Another Boolean</Name>
        <Value>True</Value>
      </property>
      <property>
        <Name>Integer</Name>
        <Value>0</Value>
      </property>
    </root>');
    

    查询 1

    select T.ItemID,
           T.CF.value('(/root/property[Name/text() = "Boolean"]/Value/text())[1]', 'varchar(32)') as Boolean,
           T.CF.value('(/root/property[Name/text() = "Integer"]/Value/text())[1]', 'varchar(32)') as Integer
    from T
    

    Results

    | ItemID | Boolean | Integer |
    |--------|---------|---------|
    |      1 |    True |       0 |
    |      2 |    True |       0 |
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-16
      • 2020-02-06
      • 1970-01-01
      • 2021-01-23
      • 2020-04-29
      • 2012-06-30
      • 1970-01-01
      • 2020-05-03
      相关资源
      最近更新 更多