Control de errores (XQuery)

La especificación W3C permite emitir errores de tipo de forma estática o dinámica y define errores estáticos, dinámicos y de tipo.

Compilación y control de errores

Las expresiones XQuery e instrucciones XML DML sintácticamente incorrectas generan errores de compilación. En la fase de compilación, se comprueba la corrección del tipo estático de las expresiones XQuery y las instrucciones DML, y se utilizan esquemas XML para detectar inferencias de tipos para XML con tipo. Si una expresión puede generar un error en tiempo de ejecución debido a una infracción de seguridad de tipos, se producen errores de tipo estático. Ejemplos de errores estáticos son la suma de una cadena a un entero y la consulta de datos con tipo en un nodo no existente

Como desviación del estándar W3C, los errores en tiempo de ejecución de XQuery se convierten en secuencias vacías. Estas secuencias se pueden propagar al resultado de la consulta como XML vacío o NULL, dependiendo del contexto de invocación.

Una conversión explícita al tipo correcto permite a los usuarios resolver errores estáticos, aunque los errores de conversión en tiempo de ejecución se transformarán en secuencias vacías.

Errores estáticos

Los errores estáticos se devuelven utilizando el mecanismo de error de Transact-SQL. En SQL Server, los errores de tipo de XQuery se devuelven de forma estática. Para obtener más información, vea XQuery y el establecimiento de tipos estáticos.

Errores dinámicos

En XQuery, la mayoría de los errores dinámicos se asignan a una secuencia vacía ("()"). No obstante, existen dos excepciones: las condiciones de sobrecarga en funciones de agregado de XQuery y los errores de validación de XML-DML. Tenga en cuenta que la mayoría de los errores dinámicos se asignan a una secuencia vacía. De lo contrario, la ejecución de consultas que se aprovecha de los índices XML puede producir errores inesperados. Por tanto, para proporcionar una ejecución eficaz sin generar errores inesperados, SQL Server Database Engine (Motor de base de datos de SQL Server) asigna los errores dinámicos a ().

A menudo, en una situación en la que el error dinámico se produciría dentro de un predicado, no emitir el error es no cambiar la semántica, porque () se asigna a False. Sin embargo, en algunos casos, devolver () en lugar de un error dinámico puede dar lugar a resultados inesperados. Los ejemplos siguientes lo muestran.

Ejemplo: utilizar la función avg() con una cadena

En el ejemplo siguiente, se llama a la función avg para calcular la media de los tres valores. Uno de estos valores es una cadena. Puesto que la instancia XML en este caso no tiene tipo, todos los datos que contiene son de tipo atómico sin tipo. La función avg() convierte estos valores al tipo xs:double antes de calcular la media. Sin embargo, el valor, "Hello", no se puede convertir al tipo xs:double y se origina un error dinámico. En este caso, en lugar de devolver un error dinámico, la conversión de "Hello" a xs:double da lugar a una secuencia vacía. La función avg() omite este valor, calcula la media de los otros dos valores y devuelve 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(//*)')

Ejemplo: utilizar la función not

Cuando se utiliza la función not en un predicado, por ejemplo, /SomeNode[not(Expression)], y la expresión origina un error dinámico, se devuelve una secuencia vacía en lugar de un error. Si se aplica not() a una secuencia vacía, se devuelve True en lugar de un error.

Ejemplo: convertir una cadena

En el ejemplo siguiente, la cadena literal "NaN" se convierte a xs:string, y después a xs:double. El resultado es un conjunto de filas vacío. Aunque la cadena "NaN" no se puede convertir correctamente a xs:double, esto no se puede determinar hasta el tiempo de ejecución, porque la cadena se convierte primero a xs:string.

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

En este ejemplo, sin embargo, se produce un error de tipo estático.

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

Limitaciones de la implementación

No se admite la función fn:error().