Contexto de expresiones y evaluación de consultas (XQuery)

El contexto de una expresión es la información que se utiliza para analizarla y evaluarla. A continuación, se muestran las dos fases de evaluación de XQuery:

  • Contexto estático: se trata de la fase de compilación de la consulta. En función de la información disponible, a veces pueden producirse errores durante este análisis estático de la consulta.

  • Contexto dinámico: se trata de la fase de ejecución de la consulta. Aunque una consulta no presente errores estáticos, como errores que se hayan producido durante la compilación de la consulta, la consulta puede devolver errores durante su ejecución.

Contexto estático

La inicialización del contexto estático se refiere al proceso que consiste en reunir toda la información de cara al análisis estático de la expresión. Como parte de la inicialización del contexto estático, se llevan a cabo los siguientes pasos:

  • La directiva de espacio en blanco de límite se establece en la opción de eliminación. Por tanto, los constructores any element y attribute no conservan en la consulta el espacio en blanco límite. Por ejemplo:

    declare @x xml
    set @x=''
    select @x.query('<a>  {"Hello"}  </a>,
    
        <b> {"Hello2"}  </b>')
    

    La siguiente consulta devuelve el siguiente resultado, porque el espacio límite se elimina durante el análisis de la expresión XQuery:

    <a>Hello</a><b>Hello2</b>
    
  • El enlace del espacio de nombres y el prefijo se inicializan para los siguientes espacios de nombres:

    • Un conjunto de espacios de nombres predefinidos.

    • Cualquier espacio de nombres definido mediante WITH XMLNAMESPACES. Para obtener más información, consulte Agregar espacios de nombres mediante WITH XMLNAMESPACES.

    • Cualquier espacio de nombres definido en el prólogo de la consulta. Tenga en cuenta que las declaraciones de espacios de nombres del prólogo pueden reemplazar la declaración de espacio de nombres de WITH XMLNAMESPACES. Por ejemplo, en la siguiente consulta, WITH XMLNAMESPACES declara un prefijo (pd) que se enlaza con el espacio de nombres (http://someURI). Sin embargo, en la cláusula WHERE, el prólogo de la consulta reemplaza el enlace.

      WITH XMLNAMESPACES ('http://someURI' AS pd)
      SELECT ProductModelID, CatalogDescription.query('
          <Product 
              ProductModelID= "{ sql:column("ProductModelID") }" 
              />
      ') AS Result
      FROM Production.ProductModel
      WHERE CatalogDescription.exist('
          declare namespace  pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
           /pd:ProductDescription[(pd:Specifications)]'
          ) = 1
      

    Todos estos enlaces de espacio de nombres se resuelven durante la inicialización del contexto estático.

  • Si se consulta una columna o variable xml con tipo, los componentes de la colección de esquemas XML asociados a la columna o variable se importan en el contexto estático. Para obtener más información, vea Comparación de XML con tipo y XML sin tipo.

  • Se pone a disposición de cada uno de los tipos atómicos de los esquemas importados una función de conversión en el contexto estático. Esto se muestra en el ejemplo siguiente. En este ejemplo, se especifica una consulta en una variable xml con tipo. La colección de esquemas XML asociada a esta variable define un tipo atómico, myType. Durante el análisis estático, hay disponible una función de conversión correspondiente al tipo, myType(). La expresión de consulta (ns:myType(0)) devuelve un valor de tipo myType.

    -- DROP XML SCHEMA COLLECTION SC
    -- go
    CREATE XML SCHEMA COLLECTION SC AS '<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="myNS" xmlns:ns="myNS"
    xmlns:s="https://schemas.microsoft.com/sqlserver/2004/sqltypes">
          <import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes"/>
          <simpleType name="myType">
                <restriction base="int">
                 <enumeration value="0" />
                  <enumeration value="1"/>
                </restriction>
          </simpleType>
          <element name="root" type="ns:myType"/>
    </schema>'
    go
    
    DECLARE @var XML(SC)
    SET @var = '<root xmlns="myNS">0</root>'
    -- specify myType() casting function in the query
    SELECT @var.query('declare namespace ns="myNS"; ns:myType(0)')
    

    En el siguiente ejemplo, la función de conversión para el tipo XML int integrado se especifica en la expresión.

    declare @x xml
    set @x = ''
    select @x.query('xs:int(5)')
    go
    

Una vez inicializado el contexto estático, se analiza la expresión de consulta (se compila). El análisis estático conlleva los siguientes pasos:

  1. Análisis de la consulta.

  2. Resolución de los nombres de tipos y funciones que se hayan especificado en la expresión.

  3. Escritura estática de la consulta. Este paso garantiza la seguridad de tipos de la consulta. Por ejemplo, la siguiente consulta devuelve un error estático, porque el operador + requiere argumentos de tipo numérico primitivo:

    declare @x xml
    set @x=''
    SELECT @x.query('"x" + 4')
    

    En el siguiente ejemplo, el operador value() requiere un valor singleton. Tal y como se especifica en el esquema XML, puede haber varios elementos <Elem>. El análisis estático de la expresión determina que no tiene seguridad de tipos y se devuelve un error estático. Para resolver este error, hay que volver a escribir la expresión y especificar explícitamente un valor singleton (data(/x:Elem)[1]).

    DROP XML SCHEMA COLLECTION SC
    go
    CREATE XML SCHEMA COLLECTION SC AS '<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="myNS" xmlns:ns="myNS"
    xmlns:s="https://schemas.microsoft.com/sqlserver/2004/sqltypes">
          <import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes"/>
          <element name="Elem" type="string"/>
    </schema>'
    go
    
    declare @x xml (SC)
    set @x='<Elem xmlns="myNS">test</Elem><Elem xmlns="myNS">test2</Elem>'
    SELECT @x.value('declare namespace x="myNS"; data(/x:Elem)[1]','varchar(20)')
    

    Para obtener más información, vea XQuery y el establecimiento de tipos estáticos.

Restricciones de implementación

A continuación se muestran las limitaciones relativas al contexto estático:

  • No se admite el modo de compatibilidad de XPath.

  • Para una construcción XML, sólo se admite el modo de construcción de eliminación. Ésta es la configuración predeterminada. Por lo tanto, el tipo del nodo de elemento construido es de tipo xdt:untyped y los atributos son de tipo xdt:untypedAtomic.

  • Sólo se admite el modo de ordenación ordenado.

  • Sólo se admite la directiva de eliminación de espacio XML.

  • No se admite la funcionalidad URI básica.

  • No se admite fn:doc() .

  • No se admite fn:collection().

  • No se proporciona un indicador estático de XQuery.

  • Se utiliza la intercalación asociada al tipo de datos xml. Esta intercalación siempre se establece en la intercalación de punto de código Unicode.

Contexto dinámico

El contexto dinámico se refiere a la información que debe estar disponible en el momento de ejecución de la expresión. Además del contexto estático, también se inicializa la siguiente información como parte del contexto dinámico:

  • El foco de la expresión, como el elemento de contexto, la posición de contexto y el tamaño de contexto, se inicializa del modo que se muestra a continuación. Tenga en cuenta que todos estos valores pueden reemplazarse por el método nodes().

    • El tipo de datos xml establece el elemento de contexto, el nodo que se va a procesar, en el nodo de documento.

    • La posición de contexto, la posición del elemento de contexto con respecto a los nodos que se van a procesar, se establece primero en 1.

    • El tamaño de contexto, el número de elementos de la secuencia que se va a procesar, se establece primero en 1, porque siempre hay un nodo de documento.

Restricciones de implementación

A continuación se muestran las limitaciones relativas al contexto dinámico:

  • No se admite las funciones de contexto de fecha y hora actuales, fn:current-date, fn:current-time y fn:current-dateTime.

  • La zona horaria implícita se fija en UTC+0 y no se puede modificar.

  • No se admite la función fn:doc(). Todas las consultas se ejecutan en columnas o variables de tipo xml.

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