查询 XML 列 - 返回关系数据

Querying an XML column - returning relational data

我有一个问题,我必须 return 包含在 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>

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

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

跳过 case 语句并将谓词放在 xPath 表达式中的 属性 name 上,您可以从中获取值。

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 |