SQL Server XQuery error: number () requires a node or nodeset,
I have the following query in SQL Server 2012:
DECLARE @xml XML
SET @xml =
'<Root>
<Value>false</Value>
</Root>'
SELECT
node.value('concat(substring("T", 1, number((./Value/text())[1] = "true")), substring("F", 1, number(not((./Value/text())[1] = "true"))))', 'NVARCHAR(MAX)') AS [ValueTF]
FROM @xml.nodes('/Root') AS input(node)
This is a ternary-style operation getter method, as described here: How do I create an if-then-else (aka trernary operator) expression into an XPath 1.0 expression?
I expect this query to return F
for ValueTF
, but instead it throws the following error message:
Msg 2374, Level 16, State 1, Line 10
a node or set of nodes is required,
XQuery [value ()]: for number ()
Even the simplified XPath number((./Value/text())[1] = "true")
returns the same error. Google search for "A node or a set of nodes is required for number ()" returns no results. The query succeeds and returns F
as expected when executed elsewhere, such as this online XPath tester .
The following query returns false
for Value
as expected, so I know that at least this part of the query is working correctly:
DECLARE @xml XML
SET @xml =
'<Root>
<Value>false</Value>
</Root>'
SELECT
node.value('(./Value/text())[1]', 'NVARCHAR(MAX)') AS [Value]
FROM @xml.nodes('/Root') AS input(node)
The W3 spec for the number function seems to indicate what xs:anyAtomicType
can be passed as an argument number
that includes xs:boolean
. So, is there a bug in my code or is it a difference in the SQL Server XQuery implementation?
source to share
Like you, I don't know why the SQL Server implementation number()
won't take a boolean argument ... or even a string, apparently! It's pretty weird.
concat()
mimic the ternary conditional operator: XPath 2.0 has the real thing!
So instead of
'concat(substring("T", 1, number((./Value/text())[1] = "true")),
substring("F", 1, number(not((./Value/text())[1] = "true"))))'
you should be able to say
'if ((./Value/text())[1] = "true") then "T" else "F"'
I have not tested this in SQL Server 2012, but it is part of XQuery and documented here so it's worth a try.
source to share
After a bit more research, I came across the following page describing implementation details number()
in SQL Server 2012: number Function (XQuery) . From this page under "Implementation Limitations":
The number () function only accepts nodes. It does not accept atomic values.
So, it seems that the problem is that the SQL Server implementation number()
will not accept a boolean argument, although it is not clear to me why it was limited this way.
source to share