如果表不存在,为什么.query()返回空字符串而不是NULL?我是SQL查询XML的新手,所以我只是在玩耍,这是意外的。
这是问题的一个例子。
declare @xml xml
set @xml = N'<xdoc><Header><OrderID>1234</OrderID><Detail><ProductID>12345</ProductID><Amount>12.50</Amount></Detail></Header></xdoc>'
SELECT
Tbl.Col.value('OrderID[1]', 'varchar(10)') as OrderID,
Tbl.Col.query('Detail') as Detail
FROM @xml.nodes('//Header') Tbl(Col)
set @xml = N'<xdoc><Header><OrderID>1234</OrderID></Header></xdoc>'
SELECT
Tbl.Col.value('OrderID[1]', 'varchar(10)') as OrderID,
Tbl.Col.query('Detail') as Detail
FROM @xml.nodes('//Header') Tbl(Col)
第一个select语句按预期返回。 “详细信息”字段是表头中表详细信息的xml。
但是,在第二个select语句上,此标头记录没有详细信息表,因此我希望该字段为null而不是空字符串。
答案 0 :(得分:0)
您想要的是可能的,但是您必须有所不同。在XML中,值NULL
由缺失节点表示。
此外,“值” 一词在这句话中非常重要。如果您要查找的元素不存在,则.value()
方法将返回NULL
。无论如何,.query()
方法都将返回XML类型的片段。
节点的XML组成。元素(任何<SomeElement>
和所有嵌套节点一起)是一种特殊的节点。元素内的浮动文本本身就是一个节点。看下面的例子:
您的XML
declare @xml xml
set @xml =
N'<xdoc>
<Header>
<OrderID>1234</OrderID>
<Detail>
<ProductID>12345</ProductID>
<Amount>12.50</Amount>
</Detail>
</Header>
</xdoc>'
-.query()
可以返回<Detail>
片段
SELECT @xml.query('/xdoc/Header/Detail');
<Detail>
<ProductID>12345</ProductID>
<Amount>12.50</Amount>
</Detail>
-该节点不存在。您得到的不是 NULL
值,而是空的XML节点
SELECT @xml.query('/xdoc/Header/Dummy'); --<-- empty XML
-现在看看.value()
SELECT @xml.value('(/xdoc/Header/Dummy)[1]','nvarchar(100)'); --<-- NULL
SELECT @xml.value('(/xdoc/Header/Detail)[1]','nvarchar(100)'); --<-- 1234512.50
SELECT @xml.value('(/xdoc/Header/Detail/text())[1]','nvarchar(100)'); --<-- NULL
SELECT @xml.value('(/xdoc/Header/Detail/ProductID)[1]','nvarchar(100)'); --<-- 12345
SELECT @xml.value('(/xdoc/Header/Detail/ProductID/text())[1]','nvarchar(100)');--<-- 12345
第一个电话很清楚,没有<Dummy>
,因此我们得到了NULL
的回报。
第二个电话可能会让您感到惊讶。 值是元素中的所有内容。在这种情况下,我们得到所有值的组合。您可能已经将其视为模拟 group_concat()的技巧。
第三次调用返回NULL
,因为text()
中没有<Detail>
...,第四个和第五个呼叫返回相同,但是最后一个带有text()
的呼叫是最具体的,因此是最佳选择。
这取决于您的需求,要查询的内容和要返回的内容。此外,您可以使用empty(SomeNode)
或not(empty(SomeNode))
之类的谓词在XPath中使用XQuery过滤器。