我遇到一个问题,我必须在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>
那么,如何用返回节点位置的东西替换[2]
中的单CF.value('(/root/property/Value)[2]', 'varchar(32)')
?
我也认识到可能会有一些更优雅的解决方案,并且对任何一个解决方案都是开放的。
答案 0 :(得分:1)
跳过case语句并将谓词放在xPath表达式中的属性名称中,在那里得到值。
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 |