XQuery y el establecimiento de tipos estáticos

XQuery en SQL Server es un lenguaje con establecimiento de tipos en modo estático. Es decir, provoca errores de tipo durante la compilación de consultas cuando una expresión devuelve un valor con un tipo o una cardinalidad no aceptado por una función o un operador determinados. Además, la comprobación de tipos estáticos también puede detectar si hay un error de asignación de tipo en una expresión de ruta de acceso de un documento XML con tipo. El compilador XQuery aplica en primer lugar la fase de normalización que agrega las operaciones implícitas, como la atomización y, a continuación, realiza la inferencia de tipos estáticos y la comprobación de tipos estáticos.

Inferencia de tipos estáticos

La inferencia de tipos estáticos determina el tipo de devolución de una expresión. Para determinarlo, obtiene los tipos estáticos de los parámetros de entrada y la semántica estática de la operación y deduce el tipo estático del resultado. Por ejemplo, el tipo estático de la expresión 1 + 2,3 se determina del modo siguiente:

  • El tipo estático de 1 es xs:integer y el de 2,3 es xs:decimal. Basándose en la semántica dinámica, la semántica estática de la operación + convierte el entero en un decimal y, a continuación, devuelve un decimal. En este caso, el tipo estático inferido será xs:decimal.

En el caso de las instancias XML sin tipo, existen tipos especiales que indican que no se ha asignado un tipo a los datos. Esta información se utiliza durante la comprobación de tipos estáticos y para realizar determinadas conversiones implícitas.

En el caso de los datos con tipo, se deduce el tipo de entrada a partir de la colección de esquemas XML que restringe la instancia de tipo de datos XML. Por ejemplo, si el esquema sólo permite elementos de tipo xs:integer, los resultados de una expresión de ruta de acceso que utilice ese elemento serán cero o más elementos de tipo xs:integer. Esto se suele mostrar con una expresión de tipo element(age,xs:integer)* en la que el asterisco (*) indica la cardinalidad del tipo resultante. En este ejemplo, la expresión puede dar como resultado cero o más elementos con el nombre "age" y el tipo xs:integer. Las demás cardinalidades son exactamente uno y se expresan únicamente mediante el nombre de tipo, cero o uno con un signo de interrogación (?), o bien 1 o más con un signo más (+).

En ocasiones, la inferencia de tipos estáticos puede deducir que una expresión siempre devolverá la secuencia vacía. Por ejemplo, si una expresión de ruta de acceso de un tipo de datos XML con tipo busca un elemento <name> en un elemento <customer> (/customer/name), pero el esquema no permite un elemento <name> en un elemento <customer>, la inferencia de tipos estáticos deducirá que el resultado está vacío. Esto se utilizará para detectar consultas incorrectas y se indicará como un error estático, a menos que la expresión sea () o data( () ).

Las reglas de inferencia detalladas se proporcionan en la semántica formal de la especificación XQuery. Microsoft la ha modificado ligeramente para trabajar con instancias de tipos de datos XML con tipo. El cambio más importante del estándar es que el nodo de documento implícito conoce el tipo de la instancia de tipo de datos XML. Como resultado, el tipo de una expresión de ruta de acceso con la forma /age se asignará de forma precisa basándose en esa información.

El Analizador de SQL Server permite ver los tipos estáticos devueltos como parte de compilaciones de consultas (evento: TSQL -> XQuery Static Type).

Comprobación de tipos estáticos

La comprobación de tipos estáticos garantiza que la ejecución en tiempo de ejecución sólo recibirá valores de tipo apropiado para la operación. Puesto que no es necesario comprobar los tipos en tiempo de ejecución, se pueden detectar posibles errores en una fase temprana de la compilación. Esto ayuda a mejorar el rendimiento. No obstante, el establecimiento de tipos estáticos requiere que el creador de la consulta sea más cuidadoso en la formulación.

A continuación se indican los tipos apropiados que se pueden utilizar:

  • Tipos permitidos explícitamente por una función u operación.
  • Un subtipo de un tipo permitido explícitamente.

Los subtipos se definen en función de las reglas de subtipo para utilizar la derivación mediante restricción o ampliación del esquema XML. Por ejemplo, un tipo S es un subtipo del tipo T si todos los valores del tipo S también son instancias del tipo T.

Además, todos los valores enteros también son valores decimales, en función de la jerarquía de tipos de esquema XML. No obstante, no todos los valores decimales son enteros. Por tanto, un entero es un subtipo de un decimal, pero no viceversa. Por ejemplo, la operación + sólo permite valores de determinados tipos, como los tipos numéricos xs:integer, xs:decimal, xs:float y xs:double. Si se pasan valores de otros tipos, como xs:string, la operación provocará un error de tipo. Esto se denomina establecimiento estricto de tipos. Los valores de otros tipos, como el tipo atómico utilizado para indicar XML sin tipo, se pueden convertir implícitamente en valores de un tipo aceptado por la operación. Esto se denomina establecimiento flexible de tipos.

Si es necesaria tras una conversión implícita, la comprobación de tipos estáticos garantiza que sólo se pasarán a una operación los valores de los tipos permitidos con la cardinalidad correcta. En el caso "string" + 1, reconocerá que el tipo estático de "string" es xs:string. Puesto que se trata de un tipo no permitido para la operación +, aparecerá un error de tipo.

Si se agrega el resultado de una expresión arbitraria E1 a una expresión arbitraria E2 (E1 + E2), la inferencia de tipos estáticos determinará en primer lugar los tipos estáticos de E1 y E2 y, a continuación, comprobará sus tipos estáticos con los tipos permitidos para la operación. Por ejemplo, si el tipo estático de E1 puede ser xs:string o xs:integer, la comprobación de tipos estáticos provocará un error de tipo, aunque puede que algunos de los valores de tiempo de ejecución sean enteros. Lo mismo ocurrirá si el tipo estático de E1 es xs:integer*. Puesto que la operación + sólo acepta exactamente un valor entero y E1 puede devolver cero o más de 1, la comprobación de tipos estáticos provocará un error.

Como se ha mencionado anteriormente, la inferencia de tipos suele inferir un tipo más general que el tipo que el usuario conoce de los datos que se pasan. En estos casos, el usuario debe volver a escribir la consulta. A continuación se exponen algunos casos habituales:

  • El tipo deduce un tipo más general, como un supertipo o una unión de tipos. Si el tipo es atómico, deberá utilizar la expresión de conversión o la función constructora para indicar el tipo estático real. Por ejemplo, si el tipo inferido de la expresión E1 es xs:string o xs:integer y la suma requiere xs:integer, deberá escribir xs:integer(E1) + E2 en lugar de E1+E2. Puede que esta expresión provoque un error de tiempo de ejecución si se detecta un valor de cadena que no se puede convertir a xs:integer. Sin embargo, ahora la expresión pasará la comprobación de tipos estáticos. En SQL Server 2005, esta expresión se asigna a la secuencia vacía.
  • El tipo deduce una cardinalidad superior a la que contienen los datos realmente. Esto ocurre a menudo, pues el tipo de datos xml puede contener más de un elemento de nivel superior y una colección de esquemas XML no puede restringirlo. Para reducir el tipo estático y garantizar que efectivamente se pasa como máximo un valor, se debe utilizar el predicado de posición [1]. Por ejemplo, para agregar 1 al valor del atributo c del elemento b debajo del elemento a de nivel superior, debe escribir (/a/b/@c)[1]+1. Además, se puede utilizar la palabra clave DOCUMENT junto con una colección de esquemas XML.
  • Algunas operaciones, como el eje parent, pierden información de tipo durante la inferencia. Debe evitar su utilización y volver a escribir la consulta si la expresión provoca un error de tipo estático.

Vea también

Otros recursos

XQuery con el tipo de datos xml

Ayuda e información

Obtener ayuda sobre SQL Server 2005