Error Handling (XQuery)
The W3C specification allows type errors to be raised statically or dynamically, and defines static, dynamic, and type errors.
Static errors are returned by using the Transact-SQL error mechanism. In SQL Server, XQuery type errors are returned statically. For more information, see XQuery and Static Typing.
In XQuery, most dynamic errors are mapped to an empty sequence ("()"). However, these are the two exceptions: Overflow conditions in XQuery aggregator functions and XML-DML validation errors. Note that most dynamic errors are mapped to an empty sequence. Otherwise, query execution that takes advantages of the XML indexes may raise unexpected errors. Therefore, to provide an efficient execution without generating unexpected errors, SQL Server 2005 Database Engine maps dynamic errors to ().
Frequently, in the situation where the dynamic error would occur inside a predicate, not raising the error is not changing the semantics, because () is mapped to False. However, in some cases, returning () instead of a dynamic error may cause unexpected results. The following are examples that illustrate this.
Consider the following query:
DECLARE @x xml SET @x='<a>Hello</a>' SELECT @x.query('xs:double(/a)')
xs:double(/a), causes a dynamic error. Converting the string that is returned by the string() function to double at run time generates a dynamic error. Instead of returning the error, the query returns an empty sequence.
In the following example, the avg function is called to compute the average of the three values. One of these values is a string. Because the XML instance in this case is untyped, all the data in it is of untyped atomic type. The avg() function first casts these values to xs:double before computing the average. However, the value,
"Hello", cannot be cast to xs:double and creates a dynamic error. In this case, instead of returning a dynamic error, the casting of
"Hello" to xs:double causes an empty sequence. The avg() function ignores this value, computes the average of the other two values, and returns 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(//*)')
When you use the not function in a predicate, for example,
/SomeNode[not(Expression)], and the expression causes a dynamic error, an empty sequence will be returned instead of an error. Applying not() to the empty sequence returns True, instead of an error.
In the following example, the literal string "NaN" is cast to xs:string, then to xs:double. The result is an empty rowset. Although the string "NaN" cannot successfully be cast to xs:double, this cannot be determined until runtime because the string is first cast to xs:string.
DECLARE @x XML SET @x = '' SELECT @x.query(' xs:double(xs:string("NaN")) ') GO
In this example, however, a static type error occurs.
DECLARE @x XML SET @x = '' SELECT @x.query(' xs:double("NaN") ') GO
The fn:error() function is not supported.