如何解决查询XML列
我有一个XML列,其格式为:
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>SubscriberBalanceBefore</name>
<value>
<string>0.0</string>
</value>
</member>
<member>
<name>TimeStamp</name>
<value>
<dateTime.iso8601>20200812T12:31:10</dateTime.iso8601>
</value>
</member>
<member>
<name>Subsc riberMSISDN</name>
<value>
<string>83000000</string>
</value>
</member>
<member>
<name>TransactionID</name>
<value>
<string>8035768</string>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>
我希望得到如下表所示的结果:
-------------------------
name | TransactionID
----------|---------------
830000000 | 8035768
我尝试使用CROSS
和OUTER APPLY
,但是它不起作用:
SELECT
X.Y.value('(name)[3]','VARCHAR(max)') as NAME_FIELD,X.Y.value('(value/string)[4]','varchar(max)') DATA_CONTENT
FROM [TABLE] T
OUTER APPLY T.xmlIn.nodes('methodResponse/params/param/value/struct/member') as X(Y)
它不给出错误,但两个字段都返回null。有人可以帮忙吗?
解决方法
您的单例标识符不正确。例如,(name)[3]
将引用name
节点的每个中的第三个member
节点。每个成员只有1个name
节点,因此NULL
值。
您需要分别引用第3个和第member
个节点:
DECLARE @XML xml = '<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>SubscriberBalanceBefore</name>
<value>
<string>0.0</string>
</value>
</member>
<member>
<name>TimeStamp</name>
<value>
<dateTime.iso8601>20200812T12:31:10</dateTime.iso8601>
</value>
</member>
<member>
<name>Subsc riberMSISDN</name>
<value>
<string>83000000</string>
</value>
</member>
<member>
<name>TransactionID</name>
<value>
<string>8035768</string>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>'
SELECT X.Y.value('(member[3]/value/string/text())[1]','varchar(max)') as NAME_FIELD,--Does this need to be a varchar(MAX)? Why not an int?
X.Y.value('(member[4]/value/string/text())[1]','varchar(max)') DATA_CONTENT --Does this need to be a varchar(MAX)? Why not an int?
FROM (VALUES(@XML))T(xmlIn)
OUTER APPLY T.xmlIn.nodes('methodResponse/params/param/value/struct') as X(Y);
但是请注意,上述解决方案取决于节点的顺序位置。使用XPATH和一些布尔逻辑,您可以避免这种情况:
SELECT X.Y.value('(member[name/text()="Subsc riberMSISDN"]/value/string/text())[1]','int') as NAME_FIELD,X.Y.value('(member[name/text()="TransactionID"]/value/string/text())[1]','int') DATA_CONTENT
FROM (VALUES(@XML))T(xmlIn)
OUTER APPLY T.xmlIn.nodes('methodResponse/params/param/value/struct') as X(Y);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。