A função SELECT combina, filtra e transforma
dados complexos de mensagens e de banco de dados.
SINTAXE
Notas:
- Você não precisa mais incluir colchetes em expressões SELECT. Isso não impede a utilização de colchetes, mas, se estiverem presentes,
serão simplesmente colchetes de escopo de expressão normais.
- Somente para o parâmetro COUNT, você pode especificar o valor de Expression a seguir
como um único asterisco (*).
Utilização
A
função SELECT é o modo comum e mais eficiente de transformar mensagens.
Você pode utilizar SELECT para:
- Reformatar mensagens de forma abrangente
- Acessar tabelas do banco de dados
- Criar uma matriz de saída que é um subconjunto de uma matriz de entrada
- Criar uma matriz de saída que contenha apenas os valores de uma matriz de entrada
- Contar o número de entradas em uma matriz
- Selecionar o valor mínimo ou máximo de um número de entradas em uma matriz
- Somas os valores em uma matriz
Introdução ao SELECT
A
função SELECT considera uma árvore (ou subárvore) de mensagens como sendo constituída de
várias
"linhas" e
"colunas", ou melhor, como uma tabela de banco de dados. Um
FieldReference em
uma cláusula FROM identifica um campo em uma árvore de mensagens e:
- O campo identificado é considerado como uma "linha" em uma tabela.
- Os irmãos do campo são considerados como outras "linhas" da mesma "tabela".
- Os filhos do campo são considerados como "colunas" da tabela.
Nota: O FieldReference em uma cláusula FROM também pode ser
uma referência de tabela que refira-se diretamente a uma tabela de banco de dados real.
O
valor de retorno da função SELECT é geralmente uma outra árvore de mensagens que
contém "linhas" cuja estrutura e conteúdo são determinados pela SelectClause.
O número de linhas no resultado é a soma de todas as "linhas" apontadas
por todas as referências de campo e referências de tabela na cláusula FROM, filtradas
pela cláusula WHERE; apenas os campos para os quais a cláusula WHERE é avaliada
como TRUE são incluídos.
O valor de retorno da função SELECT também pode
ser escalar (consulte Seleções de ITEM).
Você pode especificar
SelectClause de várias maneiras; consulte:
Seleções
Simples
Para entender a função SELECT com mais detalhes, primeiro
considere um caso simples, em que:
- A SelectClause consiste em várias expressões,
cada uma delas com uma cláusula AS Path.
- A cláusula FROM contém um único FieldReference e
uma cláusula AS CorrelationName.
A função SELECT cria uma variável local, de referência ou de correlação,
cujo nome é determinado pela cláusula AS
CorrelationName e, em
seguida, percorre sucessivamente cada
"linha" da lista de linhas derivadas
da cláusula FROM. Para cada
"linha":
- A variável de correlação é configurada para apontar para a "linha" atual.
- A cláusula WHERE (se presente) é avaliada. Se avaliada como FALSE ou
desconhecida (nula), nada será incluído na árvore de resultados e o processamento
continuará na "linha" seguinte da entrada. Caso contrário, o processamento
continuará na etapa seguinte.
- Um novo membro é incluído na lista de resultados.
- As expressões da cláusula SELECT são avaliadas e designadas a campos nomeados,
conforme determinado pela cláusula AS Path. Esses campos são campos
filhos do novo membro da lista de resultados.
Geralmente, as expressões da SelectClause e da
cláusula WHERE utilizam a variável de correlação para acessar valores de "colunas"
(ou seja, campos na árvore de mensagens de entrada) e, assim, construir uma nova árvore
de mensagens contendo dados da mensagem de entrada. A variável de correlação é referida
pelo nome especificado na cláusula AS CorrelationName ou, se uma cláusula
AS não estiver especificada, pelo nome final no FROM FieldReference (ou
seja, o nome após o último ponto).
Observe que:
- Apesar da analogia com uma tabela, você não está limitado a acessar ou
criar mensagens com uma estrutura simples semelhante a uma tabela; é possível acessar
e construir árvores com estruturas de pasta arbitrariamente profundas.
- Você não está limitado a uma "coluna" sendo um valor único; uma coluna
pode ser um valor de lista de repetição ou uma estrutura.
Esses conceitos são entendidos melhor por referência aos exemplos.
Se
a referência de campo for, na realidade, uma TableReference, a
operação será muito semelhante. Neste caso, a entrada é uma tabela de banco de dados
real e, portanto, está limitada às estruturas simples suportadas pelos bancos de dados. Entretanto,
a árvore de resultados ainda não está tão limitada.
Se houver mais de uma
referência de campo na cláusula FROM, a referência mais à direita percorre cada uma
de suas linhas para cada linha na próxima referência mais à direita e assim por diante.
O número total de linhas no resultado é, portanto, o produto do número de linhas em
cada tabela. Essas seleções são conhecidas como junções e normalmente utilizam
uma cláusula WHERE que exclui a maioria dessas linhas do resultado. As junções são
geralmente utilizadas para incluir dados do banco de dados em mensagens.
A cláusula AS
Path
é opcional. Se não for especificada, o intermediário gerará um nome padrão de acordo
com as seguintes regras:
- Se a expressão SelectClause for uma referência a um
campo ou uma coerção de uma referência a um campo, o nome do campo será utilizado.
- Caso contrário, o intermediário utilizará os nomes padrão "Column1", "Column2"
e assim por diante.
Exemplos
O exemplo a seguir executa SELECT na tabela "Parts" no esquema "Shop" no banco de dados "DSN1". Como não há nenhuma cláusula WHERE, todas as linhas são selecionadas.
Como as expressões de cláusula selecionadas (por exemplo: P.PartNumber) não contêm nenhuma cláusula AS, os campos do resultado adotam os mesmos nomes:
SET PartsTable.Part[] = SELECT
P.PartNumber,
P.Description,
P.Price
FROM Database.DSN1.Shop.Parts AS P;
Se o destino da instrução SET ("PartsTable") for uma variável do tipo ROW, após a instrução ser executada, PartsTable terá, como filhos de seu elemento raiz, um campo chamado
"Part" para cada linha da tabela. Cada um dos campos "Part" terá campos filhos chamados "PartNumber", "Description" e "Price".
Os campos filhos terão valores ditados pelo conteúdo da tabela. ("PartsTable"
também pode ser uma referência em uma árvore de mensagens).
O próximo exemplo executa um SELECT similar.
Esse caso difere do anterior pois SELECT é realizado na árvore de mensagens produzida pelo primeiro exemplo (em vez de em uma tabela de banco de dados real).
O resultado é designado a uma subpasta de "OutputRoot":
SET OutputRoot.XML.Data.TableData.Part[] = SELECT
P.PartNumber,
P.Description,
P.Price
FROM PartsTable.Part[] AS P;
Seleções
de INSERT
A cláusula INSERT é uma alternativa para a cláusula AS.
Ela designa o resultado da expressão SelectClause (que
deve ser uma linha) à própria nova linha atual, em vez de um filho dela.
O efeito disso é mesclar o resultado da linha da expressão com a linha que está
sendo gerada por SELECT. Isso a difere da cláusula AS, que sempre
gera pelo menos um elemento filho antes de incluir um resultado, enquanto
INSERT não gera nenhum. INSERT é útil ao inserir dados de outras operações
SELECT, porque permite que os dados sejam mesclados sem pastas extras.
Seleções de
ITEM
A
SelectClause pode consistir na
palavra-chave ITEM e em uma expressão única. O efeito disso é tornar os resultados
anônimos. Ou seja, o resultado é uma lista de valores do tipo retornado pela
expressão, em vez de uma linha. Essa opção tem vários usos:
- Juntamente com uma expressão escalar e a função THE, pode ser utilizada
para criar uma consulta SELECT que retorna um valor escalar único (por exemplo,
o preço de um determinado item de uma tabela).
- Juntamente com uma expressão CASE e construtores ROW, pode ser utilizada
para criar uma consulta SELECT, que cria ou manipula mensagens, na qual a
estrutura de algumas "linhas" (ou seja, repetições na mensagem) é diferente
de outras. Isso é útil para manipular mensagens que possuem uma estrutura de repetição,
mas em que nem todas as repetições possuem a mesma estrutura.
- Juntamente com um construtor ROW, pode ser utilizada para criar uma consulta
SELECT que reduz os níveis de repetição na mensagem de entrada.
Seleções
de Função de Coluna
A SelectClause pode consistir
em uma das funções COUNT, MAX, MIN e SUM operando em uma expressão.
Essas funções são conhecidas como funções de coluna. Elas retornam um valor escalar
único (não uma lista) que fornece a contagem, o máximo, o mínimo ou a soma dos
valores avaliados por Expression ao percorrer as linhas
da cláusula FROM. Se Expression for avaliada como NULL para
uma determinada linha, o valor será ignorado, de modo que a função retorne a contagem,
o máximo, o mínimo ou a soma das linhas restantes.
Apenas para a função COUNT,
Expression pode consistir em um único asterisco (*). Essa
forma conta as linhas independentemente de valores nulos.
Para tornar o resultado
um reflexo útil da mensagem de entrada, Expression geralmente
inclui a variável de correlação.
Geralmente, Expression é avaliada
quanto ao mesmo tipo de dados para cada linha. Nesses casos, o resultado das funções MAX,
MIN e SUM serão do mesmo tipo de dados que os operandos. Entretanto, os
valores retornados não precisam ser todos do mesmo tipo e, se não forem,
as regras normais de aritmética serão aplicadas. Por exemplo, se um campo
em uma estrutura de mensagem repetida contiver valores inteiros para algumas linhas
e valores flutuantes para outras, a soma segue as regras normais de adição. Isso
seria do tipo flutuante porque a operação é equivalente a somar vários
valores inteiros e flutuantes.
O resultado da função COUNT é sempre
um inteiro.
Diferenças entre
Seleções de Mensagem e de Banco de Dados
As expressões FROM em que uma variável
de correlação representa uma linha em uma mensagem se comportam um pouco diferente daquelas
em que a variável de correlação representa uma linha em uma tabela de banco de dados real.
No
caso da mensagem, um caminho envolvendo um asterisco (*) tem o significado normal;
ignora o nome do campo e localiza o primeiro campo que corresponder a outros critérios
(se houver).
No caso do banco de dados, um asterisco (*) tem, por razões históricas,
o significado especial de
"todos os campos". Esse significado especial requer
conhecimento prévio da definição da tabela de banco de dados e é suportado apenas ao
consultar o banco de dados padrão (ou seja, o banco de dados apontado pelo atributo
data source do nó). Por exemplo, as consultas a seguir retornam pares nome/valor de coluna apenas durante consulta ao banco de dados padrão:
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
Especificando as
Expressões SELECT
- SelectClause
- As expressões SelectClause podem utilizar qualquer um dos operadores
e funções do intermediário, em qualquer combinação. Elas podem fazer referência a colunas de
tabelas, campos de mensagens e nomes de correlações declarados pelos SELECTs que os contêm
e a quaisquer outras variáveis ou constantes declaradas dentro do escopo.
- AS Path
- Uma expressão AS Path é um caminho relativo (ou seja, não há um nome de correlação), mas não tem nenhuma outra restrição.
Por exemplo, pode conter:
- Índices (por exemplo, A.B.C[i])
- Especificadores de tipo de campo (por exemplo, A.B.(XML.Attribute)C )
- Caminhos multipartes (por exemplo, A.B.C )
- Expressões de nomes (por exemplo, A.B.{var})
Quaisquer expressões nesses caminhos também podem utilizar qualquer um dos
operadores e funções do intermediário, em qualquer combinação. As expressões podem fazer referência às
colunas das tabelas, campos de mensagem e nomes de correlações
declarados pelos SELECTs que os contêm e quaisquer variáveis ou
constantes declaradas.
- Cláusula FROM
- As expressões da cláusula FROM podem conter várias referências ao banco de dados,
várias referências de mensagens ou um misto dos dois. É possível unir tabelas com tabelas,
mensagens com mensagens ou tabelas com mensagens.
A cláusula FROM FieldReference pode
conter expressões de qualquer tipo (por exemplo, Database.{DataSource}.{Schema}.Table1).
Você
pode calcular um campo, origem de dados, esquema ou nome de tabela no tempo de execução.
- Cláusula WHERE
A expressão da cláusula WHERE pode utilizar qualquer um dos operadores e
funções do intermediário, em qualquer combinação. Ela pode referir-se a colunas de tabelas,
campos de mensagens e quaisquer variáveis ou constantes declaradas.
Entretanto,
lembre-se que o intermediário trata a expressão da cláusula WHERE, examinando-a
e decidindo se a expressão inteira pode ser avaliada pelo banco de dados.
Se puder, ela será fornecida ao banco de dados.
A fim de ser avaliada pelo banco de dados, ela deve utilizar somente as
funções e os operadores suportados pelo banco de dados.
Entretanto, a cláusula WHERE pode referir-se a campos de mensagens, nomes
de correlação declarados por SELECTs que os contêm e quaisquer outras variáveis ou
constantes declaradas no escopo.
Se expressão inteira não puder ser
avaliada pelo banco de dados, o intermediário procurará operadores AND de primeiro nível
e examinará cada subexpressão separadamente. Em seguida, ele tentará fornecer ao banco de dados essas subexpressões que pode avaliar,
deixando o intermediário avaliar o restante. É necessário estar ciente dessa situação por duas razões:
- Aparentemente, as alterações comuns em expressões da cláusula WHERE podem ter
grandes efeitos no desempenho. Você pode determinar a porcentagem da expressão que
foi fornecida ao banco de dados, examinando um rastreio do usuário.
- Algumas funções dos bancos de dados exibem diferenças sutis de comportamento
em comparação com as funções do intermediário.
Relação com a
Função THE
A função THE (que retorna o primeiro elemento de uma lista)
pode ser utilizada juntamente com SELECT para produzir um resultado que não seja de lista.
Isso é útil, por exemplo, quando é necessário que uma consulta SELECT retorne no
máximo um item. É útil principalmente em conjunto com ITEM (consulte Seleções de ITEM).
Diferenças do Padrão SQL
ESQL SELECT se difere do banco de dados SQL SELECT nas seguintes maneiras:
- O ESQL pode produzir dados de resultados estruturados em árvore
- O ESQL pode aceitar matrizes em cláusulas SELECT
- O ESQL possui a função THE e os parâmetros
ITEM e INSERT
- O ESQL não possui uma função SELECT ALL neste release
- O ESQL não possui uma função ORDER BY neste release
- O ESQL não possui uma função SELECT DISTINCT neste release
- O ESQL não possui parâmetros GROUP BY ou HAVING neste release
- O ESQL não possui uma função de coluna AVG neste release
Restrições
As
seguintes restrições aplicam-se ao release atual:
- Quando um comando SELECT opera em mais de uma tabela de banco de dados, todas as
tabelas devem estar na mesma instância de banco de dados. (Ou seja, as TableReferences
não devem especificar diferentes nomes de origens de dados.)
- Se a cláusula FROM referir-se a mensagens e tabelas, as tabelas deverão
preceder as mensagens na lista.