Безопасное получение значений из элемента, который может содержать разные значения - PullRequest
0 голосов
/ 30 ноября 2010

У нас есть несколько элементов xml в базе данных, которые [для более старых данных] могут иногда содержать направляющие, а иногда и целые числа.

Есть ли хороший способ вытащить только все целые числа?

Это не удастся, если элемент 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 Ответ

1 голос
/ 30 ноября 2010

Вы можете добавить предикат, чтобы сопоставлять только записи, содержащие не более 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...