XML含DLL引用命名空间,如何编写SQL查询筛选v:Width为15的记录?
搞定多命名空间XML的SQL查询问题
为啥你的查询返回NULL?
问题出在XML的根元素ObsFormElementViewModel_Of_string属于默认命名空间SXA.FormBuilder.FormElementGenerator.ViewModels,但你写的XMLNAMESPACES里没声明这个命名空间,导致SQL找不到根节点,后续取值自然全是NULL。
修正后的查询代码
WITH XMLNAMESPACES ( 'http://schemas.datacontract.org/2004/07/System.Windows.Media' as m, 'SXA.FormBuilder.Common.ViewModel' as v, 'http://www.w3.org/2001/XMLSchema' as x, 'http://www.w3.org/2001/XMLSchema-instance' as i, DEFAULT 'SXA.FormBuilder.FormElementGenerator.ViewModels' -- 补上默认命名空间 ) SELECT e.ControlID, Y.value('(v:Width)[1]', 'INT') as Width -- 用整数类型更合适,要字符串就换回VARCHAR FROM SXAFBControl e CROSS APPLY e.PropertyBagxml.nodes('ObsFormElementViewModel_Of_string') as X(Y) WHERE Y.value('(v:Width)[1]', 'INT') = 15 -- 筛选Width为15的记录
关键改动说明
- 补上默认命名空间:加了
DEFAULT '...'这行,让SQL能识别根节点所在的命名空间,才能定位到对应的元素。 - 数据类型优化:
v:Width存的是数字,用INT比VARCHAR更合理,避免不必要的类型转换问题。 - 添加筛选条件:直接在WHERE子句里过滤出Width=15的结果,不用查完所有数据再二次筛选。
- 用CROSS APPLY替代OUTER APPLY:如果只需要存在匹配节点的记录,CROSS APPLY效率更高;要是想保留没有匹配的记录,换回OUTER APPLY即可。
另一种写法(指定别名)
要是不想用DEFAULT语法,也可以给默认命名空间起个别名,比如fb,然后在节点路径里使用别名:
WITH XMLNAMESPACES ( 'http://schemas.datacontract.org/2004/07/System.Windows.Media' as m, 'SXA.FormBuilder.Common.ViewModel' as v, 'http://www.w3.org/2001/XMLSchema' as x, 'http://www.w3.org/2001/XMLSchema-instance' as i, 'SXA.FormBuilder.FormElementGenerator.ViewModels' as fb -- 给默认命名空间起别名 ) SELECT e.ControlID, Y.value('(v:Width)[1]', 'INT') as Width FROM SXAFBControl e CROSS APPLY e.PropertyBagxml.nodes('fb:ObsFormElementViewModel_Of_string') as X(Y) WHERE Y.value('(v:Width)[1]', 'INT') = 15
内容的提问来源于stack exchange,提问作者Pedro
相关产品推荐
相关产品推荐

