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() 函數。