2014-10-03 51 views
3

我在SQL Server 2012以下查詢:SQL Server的XQuery的錯誤:設定節點的節點或需要數()

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) 

這是使用導出的三元式操作的方法這裏描述:How to create an if-then-else expression (aka ternary operator) in an XPath 1.0 expression?

我希望這個查詢爲ValueTF返回F,而是它提供了以下錯誤信息:

Msg 2374, Level 16, State 1, Line 10
XQuery [value()]: A node or set of nodes is required for number()

即使簡化的XPath number((./Value/text())[1] = "true")也會返回相同的錯誤。 Google搜索「數字()需要一個節點或一組節點」不會返回任何結果。查詢成功執行並按預期在其他位置執行時返回F,如this online XPath tester

下面的查詢不會返回falseValue如預期,所以我知道該查詢的至少部分工作正常:

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) 

W3 spec for the number function似乎表明xs:anyAtomicType可以作爲參數傳遞到number,其中包括xs:boolean。那麼,在我的代碼中是否有錯誤,或者這是SQL Server的XQuery實現中的差異?

回答

1

和你一樣,我不知道爲什麼SQL Server的number()的實現不會採用布爾參數......甚至不是一個字符串,顯然!這很奇怪。但是,如果它們支持XQuery,則它們應該定義爲支持XPath 2.0,這意味着您不需要使用這個醜陋的concat()替代方法來模擬三元條件運算符:XPath 2.0具有真實性!

所以不是

'concat(substring("T", 1, number((./Value/text())[1] = "true")), 
     substring("F", 1, number(not((./Value/text())[1] = "true"))))' 

,你應該能夠說

'if ((./Value/text())[1] = "true") then "T" else "F"' 

我沒有測試過,在SQL Server 2012中,但它的XQuery的一部分,它的記錄here,所以值得一試。

+1

這在SQL Server 2012中工作,謝謝!我不確定爲什麼我的印象是我僅限於XPath 1.0。 – 2014-10-03 17:56:05

1

經過多一點研究後,我在接下來的頁面中看到了描述number()在SQL Server 2012中的實現細節:number Function (XQuery)。從下實施限制節頁:

The number() function only accepts nodes. It does not accept atomic values.

因此,它似乎是問題是,number()的SQL Server實現不會採取一個boolean參數,但爲什麼它在被限制了它不是很清楚,我辦法。