У меня проблемы с выяснением, как отфильтровать этот фрагмент XML.Я хотел бы получить svcProvNbr, где userServiceCde = OASV
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')
Попробуйте это:
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 в качестве значения.
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)
В дополнение к тому, что дал marc_s, вы можете рассмотреть возможность использования CROSS APPLY TableColumn.nodes('/') as t(c) между FROM и WHERE (при этом TableColumn - это имя столбца, содержащего XML, а затем путь в скобках).
CROSS APPLY TableColumn.nodes('/') as t(c)
TableColumn