La función SELECT combina, filtra y
transforma datos de base de datos y mensajes complejos.
SINTAXIS
Notas:
- Ya no necesita corchetes para encerrar las expresiones SELECT.
Esto no le impide utilizar corchetes pero, si están presentes, son
simplemente corchetes normales para el ámbito de expresiones.
- Para el
parámetro COUNT solamente, puede especificar el valor de la
siguiente Expresión como un solo
asterisco (*).
Uso
La
función SELECT es la forma más normal y eficiente de transformación de mensajes.
Puede utilizar SELECT para:
- Reformatear mensajes de forma más extensa
- Acceder a tablas de base de datos
- Crear una matriz de salida que sea un subconjunto de una matriz de entrada
- Crear una matriz de salida que contenga solamente los valores de una
matriz de entrada
- Contar el número de entradas de una matriz
- Seleccionar el valor mínimo o máximo de un número de entradas de una matriz
- Sumar los valores de una matiz
Introducción a SELECT
La
función SELECT considera un árbol (o subárbol) de mensaje como formado por
varias
"filas" y
"columnas", en lugar de como una tabla de
base de datos. Una
ReferenciaCampo en una cláusula
FROM identifica un campo en un árbol de mensaje y:
- El campo identificado se considera como una "fila" de una
tabla.
- Los elementos hermano del campo se consideran como otras
"filas" de la misma "tabla".
- Los elementos hijo del campo se consideran como las "columnas" de
la tabla.
Nota: La ReferenciaCampo en una cláusula FROM
también puede ser una referencia de tabla que haga referencia
directamente a una tabla de base de datos real.
Normalmente,
el valor de retorno de la función SELECT es otro árbol de mensaje que
contiene "filas" cuya estructura y contenido los determina la
CláusulaSelect.
El número de filas del resultado es la suma de todas las
"filas" a las que apuntan todas las referencias de campo y
referencias de tabla en la cláusula FROM, filtradas por la cláusula
WHERE; sólo se incluyen los campos para los que la cláusula
WHERE se evalúa en TRUE.
El valor de retorno de la función
SELECT también puede ser escalar (consulte Selecciones ITEM).
Puede
especificar la
CláusulaSelect de varias formas;
consulte:
Selecciones
simples
Para conocer la función SELECT con más detalle, tomemos
en consideración un caso simple en el que:
- La CláusulaSelect consta de varias
expresiones, cada una con una cláusula AS VíaAcceso.
- La cláusula FROM contiene una sola ReferenciaCampo y una
cláusula AS NombreCorrelación.
La función SELECT crea una variable de correlación, local y de
referencia, cuyo nombre lo proporciona la cláusula
AS
NombreCorrelación y que luego pasa, a su vez, por
cada
"fila" de la lista de filas derivadas de la cláusula FROM. Para
cada
"fila":
- Se establece la variable de correlación para que apunte a la
"fila" actual.
- Se evalúa la cláusula WHERE (si está presente). Si toma el valor
FALSE o desconocido (null), no se añade nada al árbol
resultante y el proceso continúa en la siguiente "fila" de la entrada. De lo contrario, el proceso continúa en el paso siguiente.
- Se añade un nuevo miembro en la lista de resultados.
- Se evalúan las expresiones de la cláusula SELECT y se asignan a campos
denominados según lo indicado por la cláusula AS VíaAcceso. Estos campos son campos hijo del nuevo miembro de la lista de resultados.
Normalmente, tanto las expresiones de la
CláusulaSelect como la cláusula WHERE utilizan la
variable de correlación para acceder a los valores de "columna"
(es decir, los campos en el árbol de mensaje de entrada) y crear, así, un
nuevo árbol de mensaje con datos del mensaje de entrada. Se hace referencia a la variable de correlación mediante el nombre
especificado en la cláusula AS NombreCorrelación o, si
no se especifica ninguna cláusula AS, mediante el nombre final en
FROM ReferenciaCampo (es decir, el nombre después del
último punto).
Observe que:
- A pesar de la analogía con una tabla, no está limitado a acceder o
crear mensajes con una estructura plana, similar a una tabla; puede
acceder y crear árboles con estructuras de carpeta de muchos niveles.
- No está limitado a que una "columna" tenga un solo valor;
una columna puede ser una estructura o un valor de lista de repetición.
Es más fácil entender estos conceptos mediante los ejemplos.
Si la referencia de campo es, en realidad, una
ReferenciaTabla, la operación es muy similar. En este
caso, la entrada es una tabla de base de datos real y, por tanto, está
limitada a las estructuras planas soportadas por las bases de
datos. Sin embargo, el árbol de resultados todavía no está tan limitado.
Si hay más de una referencia de campo en la cláusula
FROM, la referencia más a la derecha pasa por cada una de sus filas, para
cada fila en la segunda referencia más a la derecha, etc.
Por tanto, el número total de filas en el resultado es el
producto del número de filas en cada tabla. Estas selecciones se
denominan 'uniones' (joins) y normalmente utilizan una cláusula
WHERE que excluye la mayoría de estas fila del resultado. Las uniones
se utilizan, normalmente, para añadir datos de base de datos a los
mensajes.
La cláusula AS
VíaAcceso es opcional. Si no
se especifica, el intermediario genera un nombre por omisión siguiendo
estas normas:
- Si la expresión CláusulaSelect es una referencia a
un campo o una transformación de una referencia a un campo, se utiliza el
nombre del campo.
- De lo contrario, el intermediario utiliza los nombres por omisión
"Column1", "Column2", etc.
Ejemplos
El ejemplo
siguiente realiza una operación SELECT en la tabla "Parts" del
esquema "Shop" de la base de datos "DSN1". Puesto que no
hay ninguna cláusula WHERE, se seleccionan todas las filas.
Dado que las expresiones de la cláusula SELECT (por ejemplo, P.PartNumber)
contienen ninguna cláusula AS, los campos del resultado adoptan los
mismos nombres:
SET PartsTable.Part[] = SELECT
P.PartNumber,
P.Description,
P.Price
FROM Database.DSN1.Shop.Parts AS P;
Si el destino de la
sentencia SET ("PartsTable") es una variable de tipo ROW, una vez
ejecutada la sentencia, PartsTable tendrá, como hijos de su elemento
raíz, un campo llamado "Part" para cada fila de la tabla. Cada
uno de los campos "Part" tendrá campos hijo llamados
"PartNumber", "Description" y "Price".
Los campos hijo tendrán valores dictados por el contenido de la tabla. ("PartsTable"
podría ser también una referencia a un árbol de mensaje).
El
ejemplo siguiente realiza una operación SELECT similar. Este caso se
diferencia del anterior en que la sentencia SELECT se realiza en el árbol
de mensaje generado por el primer ejemplo (en lugar de en una tabla de
base de datos real). El resultado se asigna a una subcarpeta de
"OutputRoot":
SET OutputRoot.XML.Data.TableData.Part[] = SELECT
P.PartNumber,
P.Description,
P.Price
FROM PartsTable.Part[] AS P;
Selecciones
INSERT
La cláusula INSERT es una alternativa a la cláusula AS.
Asigna el resultado de la expresión CláusulaSelect
(que debe ser una fila) a la nueva fila actual, en lugar de a un hijo de
ella.
El efecto de ello es fusionar el resultado de fila de la expresión
en la fila que se genera mediante SELECT. Esto difiere de la cláusula
AS en que ésta siempre genera, al menos, un elemento hijo
antes de añadir un resultado, mientras que INSERT no genera ninguno. INSERT
es útil cuando se insertan datos de otras operaciones
SELECT, porque permite que los datos se fusionen sin carpetas adicionales.
Selecciones
ITEM
La
CláusulaSelect puede constar de la
palabra clave ITEM y una sola expresión. El efecto de esto es hacer que
el resultado no tenga nombre. Es decir, el resultado es una lista de
valores del tipo devuelto por la expresión, en lugar de una fila. Esta opción tiene varios usos:
- Conjuntamente con una expresión escalar y la función THE, puede
utilizarse para crear una consulta SELECT que devuelva un solo valor
escalar (por ejemplo, el precio de un elemento específico de una tabla).
- Conjuntamente con una expresión CASE y constructores ROW, puede
utilizarse para crear una consulta SELECT que cree o maneje mensajes
en los que la estructura de algunas "filas" (es decir,
repeticiones en el mensaje) sea distinta de otras. Esto es útil para manejar mensajes que tienen una estructura de
repetición, pero en los que la repetición no tienen todos la misma
estructura.
- Conjuntamente con un constructor ROW, puede utilizarse para crear una
consulta SELECT que comprima niveles de repetición en el mensaje de
entrada.
Selecciones
de función de columna
La CláusulaSelect
puede constar de una de las funciones
COUNT, MAX, MIN y SUM actuando sobre una expresión.
Estas funciones se denominan funciones de columna. Devuelven un solo valor escalar (no una lista) proporcionando el
la cuenta, el máximo, el mínimo o la suma de los valores de la
Expresión, que se han evaluado al pasar por las filas de
la cláusula FROM. Si la Expresión tiene el valor
NULL para una fila específica, se ignora ese valor, de forma que la
función devuelve la cuenta, el
máximo, el mínimo o la suma de las filas restantes.
La
Expresión puede constar de un solo asterisco (*) sólo
para la función COUNT. Este formato cuenta las filas independientemente de
los valores NULL.
Para que el resultado sea un reflejo útil del
mensaje de entrada, normalmente, la Expresión
incluye la variable de correlación.
Generalmente, la
Expresión toma el valor del mismo tipo de datos para
cada fila. En estos casos, el resultado de las funciones MAX,
MIN y SUM será del mismo tipo de datos que los operandos. Sin embargo,
no es necesario que los valores devueltos sean todos del mismo tipo, si no
lo son, se aplican las normas comunes de la aritmética. Por ejemplo, si un
campo en una estructura de mensaje de repetición contiene valores enteros
para algunas filas y valores flotantes para otras, la suma sigue las
normas comunes para la adición. Sería de tipo flotante porque la operación
es equivalente a añadir varios valores enteros y flotantes.
El resultado de la función COUNT siempre es un entero.
Diferencias
entre las selecciones de mensaje y base de datos
Las
expresiones FROM en las que una variable de correlación representa una
fila en un mensaje se comportan de forma ligeramente distinta de aquellas
en las que la variable de correlación representa una fila en una tabla de
base de datos real.
En el caso del mensaje, una vía de acceso que
contenga un asterisco (*) tiene el significado normal; ignora el nombre
del campo y busca el primer campo que coincida con los criterios restantes
(si los hay).
En el caso de la base de datos, un asterisco
(*) tiene, por motivos históricos, el significado especial de
"todos los campos". Este significado especial requiere conocimientos
avanzados de la definición de la tabla de base de datos y sólo está
soportado cuando se consulta la base de datos por omisión
(es decir, la base de datos a la que apunta el atributo
origen de datos del nodo). Por ejemplo, las consultas
siguientes devuelven parejas nombre/valor de columna sólo cuando se
consulta la base de datos por omisión:
SELECT * FROM Database.Datasource.SchemaName.Table As A
SELECT A.* FROM Database.Datasource.SchemaName.Table As A
SELECT A FROM Database.Datasource.SchemaName.Table AS A
Especificación
de expresiones SELECT
- CláusulaSelect
- Las expresiones CláusulaSelect pueden utilizar
cualquiera de los operadores y funciones del intermediario en cualquier
combinación. Pueden hacer referencia a columnas de las tablas, campos
de mensajes, nombres de correlaciones declarados en las cláusulas SELECT que
las contienen y otras variables o constantes declaradas que están dentro del ámbito.
- AS VíaAcceso
- Una expresión AS VíaAcceso es una vía de acceso
relativa (es decir, no hay ningún nombre de correlación) pero, por lo
demás, no tiene ningún tipo de restricción. Por ejemplo, puede contener:
- Índices (por ejemplo, A.B.C[i])
- Especificadores de tipo de campo (por ejemplo, A.B.(XML.Attribute)C)
- Vías de acceso de varias partes (por ejemplo, A.B.C )
- Expresiones de nombre (por ejemplo, A.B.{var})
Cualquier expresión en estas vías de acceso también puede utilizar
los operadores y funciones del intermediario en cualquier combinación. Las
expresiones pueden hacer referencia a columnas de las tablas, campos de
mensajes, nombres de correlaciones declarados en las cláusulas SELECT que
las contienen y cualquier otra variable o constante declarada.
- Cláusula FROM
- Las expresiones de la cláusula FROM puede contener varias referencias de
base de datos, varias referencias de mensajes o una combinación de los dos. Puede unir tablas con tablas, mensajes con mensajes o tablas con
mensajes.
Las ReferenciaCampo de la cláusula FROM
pueden contener expresiones de cualquier tipo (por ejemplo,
Database.{DataSource}.{Schema}.Table1).
Puede
calcular el nombre de un campo, origen de datos, esquema o tabla en tiempo
de ejecución.
- Cláusula WHERE
La expresión de la cláusula WHERE puede utilizar
cualquier operador y función del intermediario en cualquier combinación. Puede
hacer referencia a columnas de tabla, campos de mensajes y cualquier
constante o variable declarada.
Sin embargo, tenga en
cuenta que el intermediario trata
la expresión de la cláusula WHERE examinando la expresión y decidiendo
si la base de datos puede evaluar toda la expresión.
Si puede, se suministra a la base de datos. Para que pueda evaluarla la base de datos, debe utilizar únicamente las funciones y operadores a los que dé soporte la base de datos.
No obstante, la cláusula WHERE hace referencia a campos de
mensajes, nombres de correlación declarados en las cláusulas
SELECT que las contienen, y a cualquier otra variable o constante
declarada dentro del ámbito.
Si la base de datos no
puede evaluar toda la expresión, el intermediario busca los operadores AND
de nivel superior y examina cada subexpresión por separado. A continuación, intenta proporciona a la base de datos las subexpresiones que puede evaluar, dejando que el intermediario evalúe el resto. Debe tener en cuenta esta situación por dos motivos:
- Los cambios en las expresiones de la cláusula WHERE que aparentemente pueden parecer triviales pueden tener un gran impacto en el rendimiento. Puede determinar la cantidad de la expresión que se ha suministrado a la base de datos examinando un rastreo de usuario.
- Algunas funciones de base de datos se comportan de manera ligeramente
diferente del intermediario.
Relación con
la función THE
Puede utilizar la función THE (que devuelve el
primer elemento de una lista) conjuntamente con SELECT para generar un
resultado que no sea una lista.
Esto es útil, por ejemplo, cuando se necesita que una consulta
SELECT devuelva sólo un elemento. Es particularmente útil en combinación con ITEM
(consulte Selecciones ITEM).
Diferencias del estándar SQL
ESQL SELECT se diferencia de SQL SELECT para base de datos en lo siguiente:
- ESQL puede generar datos de resultado con estructura de árbol
- ESQL puede aceptar matrices en cláusulas SELECT
- ESQL tiene la función THE y los parámetros
ITEM e INSERT
- ESQL no tiene la función SELECT ALL en este release
- ESQL no tiene la función ORDER BY en este release
- ESQL no tiene la función SELECT DISTINCT en este release
- ESQL no tiene los parámetros GROUP BY ni HAVING en este release
- ESQL no tiene la función de columna AVG en este release
Limitaciones
Se
aplican las siguientes limitaciones en al release actual:
- Cuando un mandato SELECT actúa en más de una tabla de base de
datos, todas las tablas deben estar en la misma instancia de base de datos. (Es decir, las ReferenciaTabla no deben especificar
nombres de origen de datos distintos.)
- Si la cláusula FROM hace referencia a mensajes y tablas, las tablas
deben preceder a los mensajes en la lista.