Referências de Campos ESQL

Este tópico descreve como utilizar referências de campo ESQL para formar caminhos para elementos do corpo da mensagem.

A SINTAXE COMPLETA DAS REFERêNCIAS DE CAMPO é COMO MOSTRADO A SEGUIR:

Uma referência de campo consiste em um nome de correlação, seguido de zero ou mais Campos de caminho, separados por pontos (.). O nome de correlação identifica um ponto de início bem conhecido e deve ser o nome de uma constante, uma variável declarada (escalar, linha ou referência) ou um dos pontos de início predefinidos; por exemplo, InputRoot. Os Campos de caminho definem um caminho do ponto de início para o campo desejado.

Por exemplo:
InputRoot.XML.Data.Invoice
inicia o intermediário no local InputRoot (isto é, a raiz da mensagem de entrada de um nó Compute) e, em seguida, realiza uma seqüência de navegações. Inicialmente, ele navega da raiz ao primeiro campo filho denominado XML, em seguida, ao primeiro campo filho do campo XML denominado Data. Finalmente, o intermediário navega até o primeiro campo filho do campo Data, denominado Invoice. Toda vez que essa referência de campo ocorre em um programa ESQL, o campo Invoice é acessado.
Essa forma de referência de campo é simples, conveniente e normalmente a mais utilizada. No entanto, possui duas limitações:
  • Como os nomes utilizados devem ser identificadores ESQL válidos, você poderá utilizar apenas nomes que estejam de acordo com as regras de ESQL. Ou seja, os nomes só podem conter caracteres alfanuméricos (inclusive o traço sublinhado), o primeiro caractere não pode ser numérico e os nomes devem ter pelo menos um caractere de comprimento. É possível evitar essas limitações encerrando os nomes não conforme essas regras, mas em aspas duplas. Por exemplo:
    InputRoot.XML."Customer
    Data".Invoice
    Se precisar fazer referência a campos que contêm aspas, utilize dois pares de aspas em torno da referência. Por exemplo:
    Body.Message."""hello"""

    Alguns identificadores são reservados apenas como palavras-chave, mas, com exceção dos nomes de correlação, é possível utilizá-los nas referências de campo, sem a utilização de aspas duplas

  • Como os nomes dos campos aparecem no programa ESQL, eles devem ser conhecidos quando o programa for escrito. Essa limitação pode ser evitada utilizando a sintaxe alternativa com chaves ( { ... } ). Essa sintaxe permite utilizar qualquer expressão que retorne um valor não nulo de tipo caractere.
    Por exemplo:
    InputRoot.XML."Customer Data".{'Customer-'
    ||
    	CurrentCustomer}.Invoice
    no qual as faturas estão contidas em uma pasta com um nome formado pela concatenação do literal de caractere Customer- com o valor em CurrentCustomer (que, neste exemplo, deve ser uma variável declarada de caractere de tipo).

Você pode utilizar o caractere curinga asterisco (*) em um elemento de caminho para corresponder a qualquer nome. Também pode utilizar "*" para especificar um nome parcial. Por exemplo, Prefix* corresponde a qualquer nome que começa com "Prefix".

Observe que encerrar qualquer coisa em aspas duplas no ESQL torna-o um identificador; encerrar qualquer coisa em aspas simples torna-o um literal de caractere. Você deve incluir todas as cadeias de caracteres entre aspas simples.

Consulte:
  • Espaços de Nomes para o significado de combinações diferentes de espaço de nomes e nome
  • Referências de Campos de Destino para o significado de combinações diferentes de referências de campo
  • Índices para o significado de combinações diferentes de cláusulas index
  • Tipos para o significado de combinações diferentes de tipos

Espaços de Nomes

Os nomes de campo podem pertencer aos espaços de nomes. As referências de campo fornecem suporte para espaços de nomes, da seguinte maneira:
  • Cada campo de cada referência de campo que contém uma cláusula name também contém uma cláusula namespace, definindo o espaço de nomes ao qual o nome especificado pertence.
  • Cada nome de espaço de nomes pode ser definido por um identificador simples ou por uma expressão (colocado entre chaves). Se um identificador for o nome de uma constante de espaço de nomes declarada, é utilizado o valor da constante. Se uma expressão for utilizada, ela deverá retornar um valor não nulo de caractere de tipo.
  • Uma cláusula namespace * declara explicitamente que as informações do espaço de nomes são ignoradas ao localizar Campos em uma árvore.
  • Uma cláusula de espaço de nomes sem identificador, expressão ou *, ou seja, somente a presença do : , destina-se explicitamente ao espaço de nomes notarget

Índices

Cada campo de uma referência de campo pode conter uma cláusula index. Essa cláusula é denotada por colchetes ( [ ... ] ) e aceita qualquer expressão que retorne um valor não-nulo de tipo inteiro. Essa cláusula identifica qual de vários campos com o mesmo nome deve ser selecionado. Os campos são numerados a partir do primeiro, começando com 1. Se essa cláusula não estiver presente, considera-se que o primeiro campo é obrigatório. Desse modo, os dois exemplos abaixo têm exatamente o mesmo significado:
InputRoot.XML.Data[1].Invoice
InputRoot.XML.Data.Invoice[1] 
Esta construção é a mais utilizada com uma variável de índice, portanto, se um loop percorre todos estes campos em seqüência. Por exemplo:
WHILE count < 32 DO
     SET TOTAL = TOTAL + InputRoot.XML.Data.Invoice[count].Amount;
     SET COUNT = COUNT + 1
END WHILE; 
Utilize este tipo de construção com cuidado, pois ele implica em que o intermediário deve contar os campos desde o começo cada vez ao longo do loop. Se a contagem repetida for grande, o desempenho será fraco. Nesses casos, uma alternativa melhor é utilizar uma variável de referência de campo.
As expressões de índice podem ser precedidas, opcionalmente, de um sinal de menor ( < ), indicando que o campo requerido deve ser indexado a partir do último campo, não a partir do primeiro. Nesse caso, o índice 1 refere-se ao último campo e o índice 2 refere-se ao penúltimo campo. Para fins de integridade, é possível utilizar um sinal de maior para indicar a contagem a partir do primeiro campo. O exemplo abaixo mostra o código ESQL que manipula os índices, em que há quatro campos chamados Invoice.
InputRoot.XML.Data.Invoice       -- Seleciona o primeiro
InputRoot.XML.Data.Invoice[1]       -- Seleciona o primeiro
InputRoot.XML.Data.Invoice[>]    -- Seleciona o primeiro
InputRoot.XML.Data.Invoice[>1]   -- Seleciona o primeiro
InputRoot.XML.Data.Invoice[>2]   -- Seleciona o segundo
InputRoot.XML.Data.Invoice[<]    -- Seleciona o quarto
InputRoot.XML.Data.Invoice[<1]   -- Seleciona o quarto
InputRoot.XML.Data.Invoice[<2]   -- Seleciona o terceiro
InputRoot.XML.Data.Invoice[<3]   -- Seleciona o segundo 
Uma cláusula de índice também pode consistir em um par de colchetes vazio ( [] ). Isso seleciona todos os campos com nomes correspondentes. Utilize essa construção com funções e instruções que esperam listas (por exemplo, as funções SELECT, CARDINALITY, SINGULAR e EXISTS ou a instrução SET) .

Tipos

Cada campo de uma referência de campo pode conter uma cláusula type. Elas são denotadas por parênteses ( ( ) ) e aceitam qualquer expressão que retorna um valor não-nulo de tipo inteiro. A presença de uma expressão de tipo restringe os campos que são selecionados aos do tipo correspondente. Essa construção é utilizada mais freqüentemente com o XML genérico, em que há muitos tipos de campos e é possível que um campo XML contenha ambos os atributos e outros Campos XML com o mesmo nome.

Por exemplo:
<Item Value = '1234' >
          <Value>5678</Value>
</Item>

Aqui, o campo XML Item possui dois Campos filhos, ambos denominados "Value". Os Campos filhos podem ser distintos utilizando-se as cláusulas do tipo: Item.(<Domínio>.Attribute)Value para selecionar o atributo e Item.(XML.Element)Value para selecionar o campo, em que <Domínio> é um de XML, XMLNS ou XMLNSC, como determinado pelo domínio de mensagens da origem.

Restrições de Tipos

Uma restrição de tipo verifica o tipo de dados retornado por uma REFERêNCIA DE CAMPO.
Notas:
  1. ScalarDataTypeName pode ser um dos seguintes: BOOLEAN, INTEGER, INT, FLOAT, DECIMAL, DEC, DATE, TIME, TIMESTAMP, GMTTIME, GMTTIMESTAMP, INTERVAL, CHARACTER, CHAR, BLOB, BIT.

Normalmente, uma restrição de tipo faz com que o valor escalar da referência seja extraído (de um modo semelhante à função FIELDVALUE) e uma exceção seja emitida se a referência não for do tipo correto. Por definição, uma exceção será emitida para todos os campos não-existentes, porque eles são avaliados como NULL. Isso fornece uma maneira conveniente e rápida de causar exceções se campos essenciais estiverem ausentes nas mensagens.

Entretanto, quando restrições de tipos ocorrem em expressões que são candidatas para serem transmitidas a um banco de dados (por exemplo, elas estão em uma cláusula WHERE), as informações são utilizadas para determinar se a expressão pode ser especificada no banco de dados. Isso pode ser importante se uma cláusula WHERE contiver uma operação CAST em uma coluna de tabela de banco de dados. Na falta de uma restrição de tipo, como por exemplo, as expressões não podem ser especificadas no banco de dados porque o intermediário não pode informar se o banco de dados é capaz de desempenhar a conversão requerida. Entretanto, observe que você deve sempre tomar cuidado ao utilizar coerções que operam em valores de colunas, porque alguns bancos de dados possuem recursos de conversão de dados excessivamente limitados.

Resumo

*, *[..], (..)*, (..)*[..]
Nenhuma dessas formas especifica um nome ou espaço de nomes. O campo de destino pode ter qualquer nome, em qualquer espaço de nomes ou em nenhum espaço de nomes. Ele é localizado apenas por seu tipo, seu índice ou seu tipo e índice, conforme apropriado.
NameId, NameId[..], (..)NameId, (..)NameId[..]
Todos estes formatos especificam um nome, mas nenhum espaço de nomes. O campo de destino é localizado pelo espaço de nomes e nome e também pelo tipo e índice, quando apropriado.

O espaço de nomes é tomado para ser o único espaço de nomes no caminho do espaço de nomes que contém esse nome. O único espaço de nomes que pode estar no caminho é o espaço de nomes notarget.

Essas formas existiam antes da introdução dos espaços de nomes. Embora o seu comportamento tenha alterado o sentido de que agora elas comparam tanto o nome como o espaço de nomes, as transformações existentes não devem perceber nenhuma alteração no seu comportamento, pois todas as transformações existentes criam os seus Campos no espaço de nomes notarget.

: *, :*[..], (..):*, (..):*[..]
Todas essas formas especificam o espaço de nomes notarget mas nenhum nome. O campo de destino é localizado por espaço de nomes e também por tipo e índice, se apropriado.
:NameId, :NameId[..], (..):NameId, (..):NameId[..]
Todas essas formas especificam um nome e o espaço de nomes notarget. O campo de destino é localizado por espaço de nomes e nomes e também por tipo e índice, se apropriado.
* :*, *:*[..], (..)*:*, (..)*:*[..]
Nenhuma dessas formas especifica um nome ou espaço de nomes. Observe que "*:*" é equivalente a "*" e corresponde a nenhum espaço de nomes e também a qualquer espaço de nomes. O campo de destino pode ter qualquer nome, em qualquer espaço de nomes ou em nenhum espaço de nomes. Ele é localizado apenas por seu tipo, seu índice ou seu tipo e índice, conforme apropriado.
*:NameId, *:NameId[..], (..)*:NameId, (..)*:NameId[..]
Todos estes formatos especificam um nome, mas nenhum espaço de nomes. O campo de destino é localizado por nome e também por tipo e índice, se apropriado.
SpaceId:*, SpaceId:*[..], (..)SpaceId:*, (..)SpaceId:*[..]
Todos estes formatos especificam um espaço de nomes, mas nenhum nome. O campo de destino é localizado por espaço de nomes e também por tipo e índice, se apropriado.
SpaceId:NameId, SpaceId:NameId[..], (..)SpaceId:NameId, (..) SpaceId:NameId[..]
Todos estes formatos especificam um espaço de nomes e um nome. O campo de destino é localizado por espaço de nomes e nomes e também por tipo e índice, se apropriado.

Em todos os casos anteriores, um nome, ou espaço de nomes, fornecido por uma expressão contida entre chaves ({}) é equivalente a um nome fornecido como um identificador.

Por definição, o nome do espaço de nomes notarget é a cadeia vazia. A cadeia vazia pode ser selecionada por expressões que se resolvem como a cadeia vazia, o identificador vazio "" ou por referência a uma constante de espaço de nomes definida como a cadeia vazia.

Referências de Campos de Destino

A utilização de referências de campo geralmente implica na procura por um campo existente. No entanto, se o campo requerido não existir, como é geralmente o caso para referências de campo que são os destinos das instruções SET e aqueles na cláusula AS das funções SELECT, ele é criado.

Nessas situações, existe uma variedade de circunstâncias nas quais o intermediário não pode informar qual é o nome ou espaço de nomes requerido e, nesses casos, aplicam-se os seguintes princípios gerais:
  • Se a cláusula name estiver ausente ou não especificar um nome e se a cláusula espaço de nomes estiver ausente ou não especificar nem implicar um espaço de nomes (ou seja, se não houver nenhum nome nem espaço de nomes disponível), aplica-se uma das seguintes condições:
    • Se o algoritmo de designação não copiar o nome de algum campo existente, o novo campo terá o seu nome e espaço de nomes definidos como a cadeia vazia e o seu sinalizador de nome não será definido automaticamente.

      Na ausência de especificação de um tipo, o tipo de campo não é Name nem NameValue, o que indica efetivamente que o novo campo não tem nome

      .
    • Por outro lado, se o algoritmo de designação optar por copiar o nome de algum campo existente, o novo campo terá tanto o seu nome como o seu espaço de nomes copiados do campo existente e o seu sinalizador Name será definido automaticamente
  • Se a cláusula name estiver presente e especificar um nome, mas a cláusula namespace estiver ausente ou não especificar nem implicar um espaço de nomes (ou seja, se houver um nome disponível mas não um espaço de nomes), o novo campo terá:
    • Name definido como o valor especificado
    • Namespace definido como a cadeia vazia
    • o sinalizador Name definido automaticamente
  • Se a cláusula name estiver ausente ou não especificar um nome, mas a cláusula namespace estiver presente e especificar ou implicar um espaço de nomes (ou seja, se houver um espaço de nomes disponível mas não um nome), o novo campo terá:
    • Namespace definido como o valor especificado
    • Name definido como a cadeia vazia
    • o sinalizador Name definido automaticamente
  • Se a cláusula name estiver presente e especificar um nome e se a cláusula namespace estiver presente e especificar ou implicar um espaço de nomes, o novo campo terá:
    • Name definido como o valor especificado
    • Namespace definido como o valor especificado
    • o sinalizador Name definido automaticamente
Também existem casos em que o intermediário cria Campos além daqueles aos quais os campos fazem referência:
  • Cópia de árvore: novos Campos são criados por um algoritmo que utiliza uma árvore de origem como gabarito. Se o algoritmo copiar o nome de um campo de origem para um novo campo, seu espaço de nomes também será copiado.
  • Expressões de seleção anônimas: as cláusulas SELECT não são obrigadas a ter cláusulas AS; as que não tiverem definem os nomes dos Campos recém-criados como valores padrão (consulte Função SELECT).

    Estes padrões podem ser derivados de nomes de campos, nomes de colunas ou podem ser simplesmente nomes de seqüência fabricados. Se o nome for o nome de um campo, trata-se efetivamente de uma cópia de árvore e o nome do espaço de nomes será copiado como acima.

    Se não, o espaço de nomes do campo recém-criado será derivado da procura do caminho, isto é, o nome será tratado como a sintaxe NameId de uma referência de campo.

O Efeito de Configurar um Campo como NULL

Tome cuidado ao designar um valor nulo a um campo. Por exemplo, o seguinte comando exclui o campo Name:
 SET OutputRoot.XML.Msg.Data.Name = NULL;  -- exclui o campo
O modo correto de designar um valor nulo a um campo é o seguinte:
SET OutputRoot.XML.Msg.Data.Name VALUE = NULL;
-- designa um valor NULL a um campo sem excluí-lo
Nota: para usuários em retrocompatibilidade

Para fins de compatibilidade reversa, a palavra-chave LAST ainda é suportada, mas seu uso é desaconselhado. LAST não pode ser utilizada como parte de uma expressão de índice: [LAST] é válido e é equivalente a [<], mas [LAST3] não é válido.

A palavra-chave LAST foi substituída pela seguinte sintaxe de setas, que permite tanto a especificação de uma direção de procura quanto de um índice:
      Field [ > ]                   -- O primero campo, equivalente a [ 1 ]
            Field [ > (a + b) * 2 ]
      Field [ < ]                   -- O último campo, equivalente a [ LAST ]
      Field [ < 1 ]	                -- O último campo, equivalente a [ LAST ]
      Field [ < 2 ]	                -- O último, mas único campo
      Field [ < (a + b) / 3 ]
Conceitos relacionados
Visão Geral do ESQL
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback
Direitos Autorais IBM Corporation 1999, 2006 Última Atualização: 1 Sep 2006
ak04861_