Referencias de campo ESQL

Este tema describe referencias de campo ESQL.

La sintaxis completa de referencias de campo es la que se muestra a continuación:
Nota: Inicio del cambioDebe utilizar un nombre o un asterisco en toda la expresión.Fin del cambio

[<] y [>] son signos válidos. Un ejemplo que utilice < y > se muestra en la figura siguiente.

Nota para los usuarios

La palabra clave LAST todavía está soportada a fines de compatibilidad con versiones anteriores, pero se ha dejado de utilizar. LAST no se puede usar como parte de una expresión de índice: [LAST] es válido y equivale a [<], pero [LAST3] no es válido.

La palabra clave LAST se ha sustituido por la sintaxis de flecha siguiente, que permite especificar una dirección de búsqueda y un índice:
      Field [ > ]                   -- El primer elemento, equivalente a [ 1 ]
      Field [ > (a + b) * 2 ]
      Field [ < ]                   -- El último elemento, equivalente a [ LAST ]
      Field [ < 1 ]	                -- El último elemento, equivalente a [ LAST ]
      Field [ < 2 ]	                -- El penúltimo elemento
      Field [ < (a + b) / 3 ]

Una referencia de campo consta de un nombre de correlación, seguido de cero o más elementos de vía de acceso separados por puntos (.). El nombre de correlación identifica un punto inicial conocido en un árbol de mensajes. Por consiguiente, el punto inicial debe ser una variable de referencia declarada o uno de los puntos de inicio predefinido, por ejemplo, InputRoot. Los elementos de vía de acceso definen una vía de acceso desde el punto inicial al campo deseado.

Por ejemplo:
InputRoot.XML.Data.Invoice
inicia el intermediario en la ubicación InputRoot (es decir, la raíz del mensaje de entrada en un nodo Compute) y, a continuación, realiza una secuencia de navegaciones. En primer lugar, navega desde el directorio raíz al primer campo XML dependiente y, a continuación al primer campo dependiente del campo XML Data. Finalmente, el intermediario navega hasta el primer campo dependiente del campo Data, Invoice. Siempre que esta referencia de campo se produzca en un programa ESQL, se accede al campo de factura.
Este formato de referencia de campo es sencillo, útil y es el que se utiliza de manera más frecuente. No obstante, tiene dos limitaciones:
  • Dado que los nombres utilizados deben ser identificadores ESQL válidos, sólo puede utilizar nombres que cumplan las normas de ESQL. Es decir, los nombres sólo pueden contener caracteres alfanuméricos incluido el de subrayado, el primer carácter no puede ser numérico y los nombres deben tener una longitud de un carácter como mínimo. Puede evitar estas limitaciones encerrando estos nombres entre comillas. Por ejemplo:
    InputRoot.XML."Customer Data".Invoice
    Si tiene que hacer referencia a campos que contengan comillas, utilice dos pares de comillas alrededor de la referencia. Por ejemplo:
    Body.Message."""hello"""

    Algunos identificadores se reservan como palabras clave, pero puede utilizar comillas alrededor de estos identificadores para indicar que no se deben interpretar como palabras clave. Por ejemplo, SET es una palabra clave. Si tiene un mensaje que contiene un campo denominado SET al que desea hacer referencia, código Body."SET". Las palabras clave no son sensibles a las mayúsculas y minúsculas; por consiguiente, SET, Set y todas las demás combinaciones de letras mayúsculas y minúsculas se reconocen como palabras clave.

    El elemento Item del mensaje Invoice es un ejemplo de esto. Item es una palabra clave reservada, por lo que, cuando haga referencia a este elemento, debe encerrarlo entre comillas. Por ejemplo:

    InputBody.Invoice.Purchases."Item"[1].Author  
  • Dado que los nombres de los campos aparecen en el programa ESQL, deben conocerse al escribir el programa. Esta limitación se puede evitar utilizando la sintaxis alternativa que utiliza llaves ( { ... } ). Esta sintaxis permite utilizar cualquier expresión que devuelva un valor no nulo de tipo carácter.
    Por ejemplo:
    InputRoot.XML."Customer Data".{'Customer-' || 
    	CurrentCustomer}.Invoice
    en que las facturas están contenidas en una carpeta con un nombre formado al concatenar el literal de caracteres Customer- con el valor de CurrentCustomer (que debe ser una variable declarada de tipo carácter).

Si encierra cualquier serie entre comillas en ESQL, la convierte en un identificador; encerrar cualquier serie entre apóstrofos la convierte en un literal de caracteres. Debe encerrar todas las series de caracteres (CHARACTER, BLOB o BIT) entre apóstrofos.

La sintaxis existente para referencias de campo y el significado de esa sintaxis no se modifica de ninguna manera. Las características principales de la función ampliada son:
  • Cada elemento de cada referencia de campo que contiene una cláusula de nombre también puede contener una cláusula de espacio de nombres que defina el espacio de nombres al que pertenece el nombre especificado.
  • Cada nombre de espacio de nombres puede definirse mediante un identificador sencillo o mediante una expresión (encerrada entre llaves). Si un identificador es el nombre de una constante de espacio de nombres declarada, se utiliza el valor de la constante. Si se utiliza una expresión, debe devolver un valor no nulo de tipo carácter.
  • Una cláusula de espacio de nombres de * indica explícitamente que la información de espacio de nombres debe pasarse por alto al localizar elementos en un árbol.
  • Una cláusula de espacio de nombres sin identificador, expresión o *, es decir, sólo el signo : presente, se dirige explícitamente al espacio de nombres notarget.
El significado de las diferentes combinaciones de cláusulas de tipo, espacio de nombres, nombre e índice es el siguiente:
[..], *, *[..], (..), (..)[..], (..)*, (..)*[..]
Ninguno de estos formatos especifica un nombre o espacio de nombres. Por consiguiente, el elemento de destino se localiza por su tipo e índice, o sólo por su índice. Estos formatos existían antes de este cambio y su comportamiento no ha cambiado de ninguna manera.
NameId, NameId[..], (..)NameId, (..)NameId[..]
Todos estos formatos especifican un nombre pero ningún espacio de nombres. El elemento de destino se localiza por el espacio de nombres y el nombre y también por el tipo y el índice si corresponde.

El espacio de nombres se considera el único espacio de nombres de la vía de acceso de espacios de nombres que contiene este nombre. El único espacio de nombres de la vía de acceso es el espacio de nombres notarget.

Todos estos formatos existían antes de este cambio. Aunque su comportamiento ha cambiado en el sentido de que ahora comparan tanto el nombre como el espacio de nombres, las transformaciones existentes no deben ver ningún cambio en su comportamiento porque todas las transformaciones existentes crean sus elementos en el espacio de nombres notarget.

:*, :*[..], (..):*, (..):*[..]
Todos estos formatos especifican el espacio de nombres notarget pero ningún nombre. El elemento de destino se localiza por su espacio de nombres y también por el tipo y el índice si corresponde.
:NameId, :NameId[..], (..):NameId, (..):NameId[..]
Todos estos formatos especifican un nombre y el espacio de nombres notarget. El elemento de destino se localiza por el espacio de nombres y también por el tipo y el índice si corresponde.
*:*, *:*[..], (..)*:*, (..)*:*[..]
Ninguno de estos formatos especifica un nombre o un espacio de nombres. El elemento de destino se localiza por su tipo e índice, o sólo por su índice.
*:NameId, *:NameId[..], (..)*:NameId, (..)*:NameId[..]
Todos estos formatos especifican un nombre pero ningún espacio de nombres. El elemento de destino se localiza por el nombre y también por el tipo y el índice si corresponde.
SpaceId:*, SpaceId:*[..], (..)SpaceId:*, (..)SpaceId:*[..]
Todos estos formatos especifican un espacio de nombres pero ningún nombre. El elemento de destino se localiza por el espacio de nombres y también por el tipo y el índice si corresponde.
SpaceId:NameId, SpaceId:NameId[..], (..)SpaceId:NameId, (..)SpaceId:NameId[..]
Todos estos formatos especifican un espacio de nombres y un nombre. El elemento de destino se localiza por el espacio de nombres y también por el tipo y el índice si corresponde.

En todos los casos anteriores, un nombre o un espacio de nombres, suministrado por una expresión encerrada entre llaves ({}), es equivalente al nombre suministrado como identificador.

Por definición, el nombre del espacio de nombres notarget es la serie vacía. La serie vacía se puede seleccionar con expresiones que se evalúan en serie vacía, el identificador vacío "", o haciendo referencia a una constante de espacio de nombres definida como serie vacía.

El uso de referencias de campo suele implicar la búsqueda de un elemento existente. Esto es cierto para referencias de campo que sean los destinos de sentencias SET y los de cláusulas AS de sentencias SELECT. Si el elemento necesario no existe, se creará.

En todas estas situaciones hay diversas circunstancias en que el intermediario no puede distinguir cuál es el nombre o espacio de nombres necesario; en estas situaciones se aplican los principios generales siguientes:
  • Si la cláusula de nombre está ausente o no especifica un nombre y la cláusula de espacio de nombres está ausente o no especifica ni implica un espacio de nombres (es decir, no hay ningún nombre o espacio de nombres disponible), se aplica una de las condiciones siguientes:
    • Si el algoritmo de asignación no copia el nombre de algún elemento existente, el nuevo elemento tiene su nombre y espacio de nombres establecido en la serie vacía y su distintivo de nombre no se establece automáticamente.

      En ausencia de una especificación de tipo, el tipo del elemento no es Nombre ni ValorNombre, lo que efectivamente indica que el nuevo elemento carece de nombre

      .
    • De lo contrario, si el algoritmo de asignación opta por copiar el nombre de algún elemento existente, se copiará el nombre y espacio de nombres del elemento existente en el nuevo elemento y su distintivo Nombre se establecerá automáticamente.
  • Si la cláusula de nombre está presente y especifica un nombre, pero la cláusula de espacio de nombres está ausente o no especifica ni implica un espacio de nombres (es decir, hay un nombre disponible pero no un espacio de nombres), el nuevo elemento dispondrá de lo siguiente:
    • Nombre establecido en el valor dado
    • EspacioNombres establecido en la serie vacía
    • Distintivo Nombre establecido automáticamente
  • Si la cláusula de nombre está ausente o no especifica un nombre, pero la cláusula de espacio de nombres está presente y especifica o implica un espacio de nombres (es decir, hay un espacio de nombres disponible pero no un nombre), el nuevo elemento dispondrá de lo siguiente:
    • EspacioNombres establecido en el valor dado
    • Nombre establecido en la serie vacía
    • Distintivo Nombre establecido automáticamente
  • Si la cláusula de nombre está presente y especifica un nombre, y la cláusula de espacio de nombres está presente y especifica o implica un espacio de nombres, el nuevo elemento dispondrá de lo siguiente:
    • Nombre establecido en el valor dado
    • EspacioNombres establecido en el valor dado
    • Distintivo Nombre establecido automáticamente
También hay casos en que el intermediario crea elementos además de los referenciados por las referencias de campo:
  • Copia de árbol: los elementos nuevos se crean mediante un algoritmo que utiliza un árbol de origen como plantilla. Si el algoritmo copia el nombre de un elemento de origen en un elemento nuevo, también se copiará su espacio de nombres.
  • Expresiones de selección anónimas: no es obligatorio que las cláusulas SELECT tengan cláusulas AS; las que no las tienen, establecen los nombres de los elementos recién creados con los valores por omisión (consulte el apartado Función SELECT).

    Estos valores por omisión se pueden derivar de nombres de elemento, nombres de columna, o simplemente pueden ser nombres de secuencia generados. Si el nombre es un nombre de elemento, es efectivamente una copia de árbol y el nombre del espacio de nombres se copia como se ha indicado antes.

    De lo contrario, el espacio de nombres del elemento recién creado se deriva buscando en la vía de acceso, es decir, el nombre se trata como la sintaxis de IDNombre de una referencia de campo.

Cada elemento de una referencia de campo puede contener una cláusula de índice. Esta cláusula se indica con corchetes ( [ ... ] ) y acepta cualquier expresión que devuelva un valor no nulo de tipo entero. Esta cláusula identifica, entre varios campos con el mismo nombre, cuáles se han de seleccionar. Los campos se numeran desde el primero, empezando por uno. Si esta cláusula no está presente, se supone que es necesario el primer campo. Así pues, los dos ejemplos siguientes tienen exactamente el mismo significado:
InputRoot.XML.Data[1].Invoice
InputRoot.XML.Data.Invoice[1] 
Esta construcción se utiliza con mayor frecuencia con una variable de índice, de manera que un bucle pasa por todos estos campos en secuencia. Por ejemplo:
WHILE count < 32 DO
     SET TOTAL = TOTAL + InputRoot.XML.Data.Invoice[count].Amount;
END WHILE; 
Utilice esta clase de construcción con cuidado, porque implica que el intermediario debe contar los campos desde el principio cada vez que da la vuelta al bucle. Si la cuenta de repeticiones es larga, el rendimiento es mediocre. En estos casos, es una mejor alternativa el utilizar una variable de referencia de campo.
Opcionalmente, las expresiones pueden ir precedidas de un signo menor que ( < ), que indica que el campo obligatorio se debe indexar desde el último campo, no desde el primero. En este caso el índice 1 hace referencia al último elemento y el índice 2 hace referencia al penúltimo elemento. Para completar la operación, puede utilizar un signo mayor que para indicar que se cuente desde el primer campo. El ejemplo que se muestra a continuación muestra código ESQL que maneja índices donde hay cuatro campos denominados Invoice.
InputRoot.XML.Data.Invoice       -- Selecciona el primero
InputRoot.XML.Data.Invoice[1]    -- Selecciona el primero
InputRoot.XML.Data.Invoice[>]    -- Selecciona el primero
InputRoot.XML.Data.Invoice[>1]   -- Selecciona el primero
InputRoot.XML.Data.Invoice[>2]   -- Selecciona el segundo
InputRoot.XML.Data.Invoice[<]    -- Selecciona el cuarto
InputRoot.XML.Data.Invoice[<1]   -- Selecciona el cuarto
InputRoot.XML.Data.Invoice[<2]   -- Selecciona el tercero
InputRoot.XML.Data.Invoice[<3]   -- Selecciona el segundo 
Una cláusula de índice también puede consistir en un par de corchetes vacío ( [] ). Esto selecciona todos los campos que tengan nombres coincidentes. Utilice esta construcción con funciones que esperan listas (por ejemplo, SELECT o CARDINALITY).

Cada elemento de una referencia de campo puede contener una cláusula de tipo. Se indican con paréntesis ( ( ) ) y aceptan cualquier expresión que devuelva un valor no nulo de tipo entero. La presencia de una expresión de tipo limita los campos seleccionados a aquéllos de tipo coincidente. Esta construcción se utiliza con mayor frecuencia con XML genérico, en que hay muchos tipos de elementos y es posible que un elemento XML contenga ambos atributos y elementos XML adicionales con el mismo nombre.

Por ejemplo:
<Item Value = '1234' >
     <Value>5678</Value>
</Item>
Aquí, el elemento XML Item tiene dos elementos dependientes y ambos se denominan "Value". Los elementos dependientes se pueden distinguir mediante cláusulas de tipo: Item.(XML.Attribute)Value para seleccionar el atributo y Item.(XML.Element)Value para seleccionar el elemento.

Conceptos relacionados
ESQL

Tareas relacionadas
Desarrollo de ESQL
Acceso a varias apariciones conocidas de un elemento