从可以包含不同值的元素安全地检索值

时间:2010-11-30 17:09:04

标签: sql xml sql-server-2008

我们在数据库中有一些xml元素[对于旧数据]有时可能包含guid,有时包含整数。

是否有一种很好的方法可以拔出所有的积分器?

如果value元素包含guid!

,则会失败
select
ra.*,
t.c.value('.', 'int') as organisationId
from 
   Audit.EmployeeAudit ra
   cross apply ra.EmployeeXml.nodes('//*:employee/*:property[*:name="ORG"]/*:value') t(c)

示例Xml

<employee>
  <property>
    <name>ORG</name>
    <value>39</value> <!-- Sometimes this will be a guid -->
    <description>Leeds</description>
  </property>
</employee>

1 个答案:

答案 0 :(得分:1)

您可以添加谓词,仅匹配小于或等于10个字符的条目。

;with EmployeeAudit as
(

SELECT CAST('<employee><property>
   <name>ORG</name>
   <value>39</value> <!-- Sometimes this will be a guid -->
   <description>Leeds</description>
</property></employee>
' AS XML) AS EmployeeXml
UNION ALL
SELECT CAST('<employee><property>
   <name>ORG</name>
   <value>2FD29F11-59FC-47FD-BC30-DD330A53284E</value> 
   <description>Leeds</description>
</property></employee>
' AS XML)
)
select
ra.*,
t.c.value('.', 'int') as organisationId
from 
   EmployeeAudit ra
   cross apply 
   ra.EmployeeXml.nodes
   ('//*:employee/*:property[*:name="ORG"]/*:value[string-length() <= 10]') t(c)

或者实际上这可能会更健壮

('//*:employee/*:property[*:name="ORG"]/*:value[ceiling(.) = .]') t(c)