错误处理 (XQuery)

适用于:SQL Server

W3C 规范允许静态或动态引发类型错误,并定义了静态错误、动态错误和类型错误。

编译和错误处理

语法不正确的 Xquery 表达式和 XML DML 语句会返回编译错误。 编译阶段会检查 XQuery 表达式和 DML 语句的静态类型正确性,并针对类型化的 XML 使用 XML 架构进行类型推理。 如果表达式在运行时由于类型安全冲突而失败,会引起静态类型错误。 静态错误的示例包括将字符串添加到整数,以及在不存在的节点中查询类型化的数据。

与 W3C 标准有所不同的是,XQuery 运行时错误被转换为空序列。 这些序列根据调用上下文,可以作为空 XML 或 NULL 传播到查询结果。

通过显式转换为正确的类型,用户可以解决静态错误的问题,尽管运行时转换错误将被转换为空序列。

静态错误

静态错误是使用 Transact-SQL 错误机制返回的。 在 SQL Server 中,XQuery 类型错误以静态方式返回。 有关详细信息,请参阅 XQuery 和静态类型化

动态错误

在 XQuery 中,大部分动态错误都映射到一个空序列(即“()”)。 不过,有两个例外:XQuery 聚合函数中的溢出条件和 XML-DML 验证错误。 请注意,大部分动态错误都映射到一个空序列。 另外,使用 XML 索引的查询执行可能引发错误。 因此,为了在不生成意外错误的情况下提供高效的执行,SQL Server数据库引擎会将动态错误映射到 () 。

通常,在谓词内出现动态错误的情况下,不引发错误就不会更改语义,因为 () 映射到 False。 但是,在某些情况下,返回 () 而不返回动态错误可能导致意外结果。 下列示例说明了这一点。

示例:使用带字符串的 avg() 函数

在以下示例中,调用 avg 函数 来计算三个值的平均值。 这些值中的一个是字符串。 由于此情况下的 XML 实例是非类型化的,因此其中的所有数据都是非类型化的原子类型。 avg () 函数先将这些值强制转换为 xs:double,然后再计算平均值。 但是, "Hello"值 无法强制转换为 xs:double ,并产生动态错误。 在这种情况下,转换为 xs:double 会导致空序列,"Hello"而不是返回动态错误。 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 函数

在谓词中使用 not 函数 (例如 /SomeNode[not(Expression)]),并且表达式会导致动态错误时,将返回空序列而不是错误。 对空序列应用 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 () 函数。

另请参阅

Xquery 语言参考 (SQL Server)
XQuery 基础知识