錯誤處理 (XQuery)

W3C 規格允許靜態或動態地引發類型錯誤,以及定義靜態、動態及類型錯誤。

編譯和錯誤處理

句法不正確的 Xquery 運算式及 XML DML 陳述式會傳回編譯錯誤。編譯階段會檢查 XQuery 運算式及 DML 陳述式的靜態類型正確性,並針對具類型的 XML 的類型推斷來使用 XML 結構描述。如果因為類型安全違規,而導致運算式在執行階段失敗,就會引發靜態類型錯誤。靜態錯誤的範例包括:加入字串至整數,以及針對具類型的資料來查詢不存在的節點。

XQuery 執行階段錯誤會轉換成空的序列,這一點有違 W3C 標準。依據引動過程內容,這些序列可能會以空的 XML 或 NULL 傳播至查詢結果。

雖然執行階段轉換錯誤會被轉換成空的序列,但明確地轉換為正確的類型可讓使用者解決靜態錯誤。

靜態錯誤

靜態錯誤是使用 Transact-SQL 錯誤機制傳回。在 SQL Server 中,會靜態地傳回 XQuery 類型錯誤。如需詳細資訊,請參閱<XQuery 與靜態類型>。

動態錯誤

在 XQuery 中,大部份動態錯誤會對應到空白時序 ("()")。但是,有兩個例外狀況:XQuery 彙總函數中的溢位條件,以及 XML-DML 驗證錯誤。請注意,大部份動態錯誤會對應到空白時序。否則,利用 XML 索引的優點而執行的查詢可能會發生意外的錯誤。因此,為了使執行有效率又不會產生意外的錯誤,SQL Server Database Engine 會將動態錯誤對應到 ()。

因為 () 是對應到 False,所以在動態錯誤在述詞內發生的情況下,經常不會引發錯誤而未改變語意。但是,在某些情況下,傳回 () 而非動態錯誤,可能會導致非預期的結果。以下是說明此點的範例。

範例:搭配字串使用 avg() 函數

在以下範例中,會呼叫 avg 函數以計算三個值的平均值。其中一個值是一個字串。因為此例中的 XML 執行個體不具類型,所以其內含的所有資料都屬於不具類型的不可部份完成類型。avg() 函數會先將值轉換成 xs:double 之後,再計算平均值。但是,無法將值 "Hello" 轉換成 xs:double,因而產生一個動態錯誤。在此情況下,將 "Hello" 轉換成 xs:double 會導致產生空白時序,而不是傳回動態錯誤。avg() 函數會忽略此值,而計算其餘兩值的平均值,然後傳回 150。

DECLARE @x xml
SET @x=N'<root xmlns:myNS="test">
 <a>100</a>
 <b>200</b>
 <c>Hello</c>
</root>'
SELECT @x.query('avg(//*)')

範例:使用 not 函數

當您在述詞 (例如 /SomeNode[not(Expression)]) 中使用 not 函數,而且運算式導致動態錯誤發生時,將會傳回空白時序而不是錯誤。將 not() 套用到空白時序就會傳回 True 而不是錯誤。

範例:轉換字串

在以下範例中,會將常值字串 "NaN" 轉換成 xs:string,然後再轉換成 xs:double。結果會是一個空白資料列集。雖然無法順利將字串 "NaN" 轉換成 xs:double,但是因為此字串會先轉換成 xs:string,所以此點要到執行階段才會確定。

DECLARE @x XML
SET @x = ''
SELECT @x.query(' xs:double(xs:string("NaN")) ')
GO

但是在此範例中,會發生靜態類型錯誤。

DECLARE @x XML
SET @x = ''
SELECT @x.query(' xs:double("NaN") ')
GO

實行限制

不支援 fn:error() 函數。