фильтрация результирующего набора с использованием xquery в столбце xml sql - PullRequest
1 голос
/ 27 мая 2011

У меня проблемы с выяснением, как отфильтровать этот фрагмент XML.Я хотел бы получить svcProvNbr, где userServiceCde = OASV

<dataExtract xmlns="http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS/dataExtract.xsd">
   <shipment>
      <location lctnSeqNbr="001">
         <lctnServiceProvider>
            <userServiceCde>EASV</userServiceCde>
            <svcProvNbr>1470-000</svcProvNbr>
            <svcProvTypeCde>A</svcProvTypeCde>
         </lctnServiceProvider>
         <lctnServiceProvider>
            <userServiceCde>OASV</userServiceCde>
            <svcProvNbr>1470-000</svcProvNbr>
            <svcProvTypeCde>A</svcProvTypeCde>
         </lctnServiceProvider>
      </location>
   </shipment>
</dataExtract>

Я пробовал несколько разных способов, но не повезло

xmlalliedxml.query
    ('declare namespace r = "http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS";
     data(/r:dataExtract/r:shipment/r:location[@lctnSeqNbr=sql:variable("@vcSegmentNo")]/r:lctnServiceProvider.userServiceCde[.="OASV"]/r:svcProvNbr)')

и

xmlalliedxml.query
    ('declare namespace r = "http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS";
     for $sp in /r:dataExtract/r:shipment/r:location[@lctnSeqNbr=sql:variable("@vcSegmentNo")]/r:lctnServiceProvider/r:svcProvNbr
 where $sp/r:dataExtract/r:shipment/r:location[@lctnSeqNbr=sql:variable("@vcSegmentNo")]/r:lctnServiceProvider/r:userServiceCde[.="OASV"]
 return
 $sp')

Ответы [ 2 ]

1 голос
/ 27 мая 2011

Попробуйте это:

DECLARE @input XML = '<dataExtract xmlns="http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS/dataExtract.xsd">
 <shipment>
   <location lctnSeqNbr="001">
     <lctnServiceProvider>
       <userServiceCde>EASV</userServiceCde>
       <svcProvNbr>1470-000</svcProvNbr>
       <svcProvTypeCde>A</svcProvTypeCde>
     </lctnServiceProvider>
     <lctnServiceProvider>
       <userServiceCde>OASV</userServiceCde>
       <svcProvNbr>1470-001</svcProvNbr>
       <svcProvTypeCde>A</svcProvTypeCde>
     </lctnServiceProvider>
   </location>
 </shipment>
</dataExtract>'

;WITH XMLNAMESPACES('http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS' AS ns)
SELECT
    @input.value('(ns:dataExtract/ns:shipment/ns:location/ns:lctnServiceProvider[ns:userServiceCde="OASV"]/ns:svcProvNbr)[1]', 
                 'varchar(50)') AS 'Service Provider Number"

Я изменил ваш XML, чтобы можно было разделить две записи, и этот оператор SELECT действительно возвращает 1470-001 в качестве значения.

Обновление: , чтобы сделать это из столбца в таблице, используйте этот код:

;WITH XMLNAMESPACES('http://dtd-sirvahub.sirva.com/xml/SCHEMA/ATS' AS ns)
SELECT
    XmlAllied.value('(ns:dataExtract/ns:shipment/ns:location/ns:lctnServiceProvider[ns:userServiceCde="OASV"]/ns:svcProvNbr)[1]', 
                 'varchar(50)') AS 'Service Provider Number"
FROM 
    dbo.AutoExtract
WHERE
    (some condition here)
0 голосов
/ 26 сентября 2012

В дополнение к тому, что дал marc_s, вы можете рассмотреть возможность использования CROSS APPLY TableColumn.nodes('/') as t(c) между FROM и WHERE (при этом TableColumn - это имя столбца, содержащего XML, а затем путь в скобках).

...