适用范围:SQL Server
W3C 规范允许静态或动态引发类型错误,并定义了静态错误、动态错误和类型错误。
编译和错误处理
编译错误是从语法上不正确的 Xquery 表达式和 XML DML 语句返回的。 编译阶段会检查 XQuery 表达式和 DML 语句的静态类型正确性,并针对类型化的 XML 使用 XML 架构进行类型推理。 如果表达式在运行时由于类型安全冲突而失败,会引起静态类型错误。 静态错误的示例包括将字符串添加到整数,以及在不存在的节点中查询类型化的数据。
与 W3C 标准有所不同的是,XQuery 运行时错误被转换为空序列。 这些序列可能会传播为空 XML 或 NULL 查询结果,具体取决于调用上下文。
通过显式转换为正确的类型,用户可以解决静态错误的问题,尽管运行时转换错误将被转换为空序列。
注释
分析 XQuery 分析器引发的错误(例如,XML 数据类型方法中引用的 XML 中的语法错误)中止活动事务,而不考虑当前会话的 XACT_ABORT 设置。
静态错误
使用 Transact-SQL 错误机制返回静态错误。 在 SQL Server 中,以静态方式返回 XQuery 类型错误。 有关详细信息,请参阅 XQuery 和静态键入。
动态错误
在 XQuery 中,大部分动态错误都映射到一个空序列(即“()”)。 不过,有两个例外:XQuery 聚合函数中的溢出条件和 XML-DML 验证错误。 大多数动态错误都映射到空序列。 否则,利用 XML 索引优势的查询执行可能会引发意外错误。 因此,为了提供高效执行而不生成意外错误,SQL Server 数据库引擎将动态错误映射到 ()。
通常,在谓词内发生动态错误的情况下,不引发错误不会更改语义,因为 () 映射到 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() 函数。