如何通过SQL从指定XML中提取nrZamowienia节点的值?
解决SQL从带命名空间的XML中提取指定节点值的问题
你的问题出在两个关键点上:XML命名空间未处理和节点路径不匹配。咱们一步步来修正:
问题分析
你的XML根节点是<ns2:powiadomOZdarzeniu>,它绑定了命名空间http://cyfrowypolsat.pl/interfejsy/umowy/zamowieniaom/v1/Zdarzenie,而你原来的查询既没声明这个命名空间,也没使用正确的节点层级——你直接从/powiadomienie开始查询,但实际上powiadomienie是根节点powiadomOZdarzeniu的子节点,而且所有节点都属于这个命名空间。
正确解法
你需要用WITH XMLNAMESPACES来声明命名空间,然后调整节点路径到正确的层级。这里提供几种可行的写法:
写法1:使用默认命名空间
这种方式会把指定的命名空间设为默认,查询时不用写前缀:
DECLARE @XML xml SET @XML = (SELECT InXML FROM ServiceBrokerQueueFault WHERE id=29140) -- 声明默认命名空间,匹配XML中的ns2绑定的地址 WITH XMLNAMESPACES(DEFAULT 'http://cyfrowypolsat.pl/interfejsy/umowy/zamowieniaom/v1/Zdarzenie') SELECT -- 直接提取powiadomienie节点下的nrZamowienia值 x.Rec.value('(nrZamowienia)[1]', 'nvarchar(2000)') AS NrZamowienia FROM @XML.nodes('/powiadomOZdarzeniu/powiadomienie') AS x(Rec)
写法2:显式指定命名空间前缀
如果你想明确区分命名空间,可以显式声明前缀(和XML里的ns2保持一致更清晰):
DECLARE @XML xml SET @XML = (SELECT InXML FROM ServiceBrokerQueueFault WHERE id=29140) -- 声明ns2前缀对应的命名空间 WITH XMLNAMESPACES('http://cyfrowypolsat.pl/interfejsy/umowy/zamowieniaom/v1/Zdarzenie' AS ns2) SELECT x.Rec.value('(ns2:nrZamowienia)[1]', 'nvarchar(2000)') AS NrZamowienia FROM @XML.nodes('/ns2:powiadomOZdarzeniu/ns2:powiadomienie') AS x(Rec)
为什么这样能行?
WITH XMLNAMESPACES让SQL Server识别XML中带前缀的节点,不会因为命名空间不匹配而忽略它们。- 调整后的节点路径
/powiadomOZdarzeniu/powiadomienie(或带前缀的版本)精准对应了XML的层级结构:根节点 → powiadomienie子节点 → nrZamowienia节点。 - 使用
.value()直接提取值比先query()再.value()更高效,避免了中间XML片段的创建。
内容的提问来源于stack exchange,提问作者Dominika
相关产品推荐
相关产品推荐

