Referências de Campos ESQL

Este tópico descreve as referências de campos ESQL.

A sintaxe completa das referências de campo é como mostrado a seguir:
Nota: Início da mudançaVocê deve especificar um nome ou um asterisco ao longo.Fim da mudança

[<] e [>] são legítimos. Um exemplo da utilização de < e > é mostrado na figura a seguir.

Nota aos usuários

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 primeiro elemento, equivalente a [ 1 ]
      Field [ > (a + b) * 2 ]
            Field [ < ]                       -- O último elemento, equivalente a [ LAST ]
            Field [ < 1 ]			-- O último elemento, equivalente a [ LAST ]
            Field [ < 2 ]			-- O último, mas único elemento
            Field [ < (a + b) / 3 ]

Uma referência de campo consiste em um nome de correlação, seguido de zero ou mais elementos de caminho, separados por pontos (.). O nome de correlação identifica um ponto de início bem conhecido em uma árvore de mensagem. O ponto de início deve ser, portanto, uma variável de referência declarada ou um dos pontos de início predefinidos, por exemplo, InputRoot. Os elementos 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 até o primeiro campo filho XML; em seguida, para o primeiro campo filho do campo XML Data. Finalmente, o intermediário navega até o primeiro campo filho do campo Data, 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. Você pode evitar essas limitações, colocando tais nomes entre 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 como palavras-chave, mas você pode utilizar aspas duplas para esses identificadores para indicar que eles não devem ser interpretados como palavras-chave. Por exemplo, SET é uma palavra-chave. Se você tiver uma mensagem que contenha um campo chamado SET ao qual deseja fazer referência, escreva Body."SET".As palavras-chave não fazem distinção entre maiúsculas e minúsculas, portanto SET, Set e todas as outras combinações são reconhecidos como palavras-chave.

    O elemento Item na mensagem Invoice é um exemplo disso. Item é uma palavra-chave reservada; portanto, ao fazer referência a esse elemento, é necessário delimitá-lo com aspas duplas. Por exemplo:

    InputBody.Invoice.Purchases."Item"[1].Author  
  • 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
    em que as faturas (invoices) estão contidas em uma pasta com um nome formado pela concatenação do literal caractere Customer- com o valor de CurrentCustomer (que deve ser uma variável declarada de tipo caractere).

Colocar algo entre aspas duplas no ESQL torna-o um identificador; colocar algo entre aspas simples torna-o um literal caractere. Você deve colocar todas as cadeias de caracteres (CHARACTER, BLOB ou BIT) entre aspas simples.

A sintaxe existente para referências de campos e o significado dessa sintaxe não são alterados de nenhuma maneira. Os principais recursos da função avançada são:
  • Cada elemento de cada referência de campo que contenha uma cláusula de nome também pode conter uma cláusula de espaço de nomes que define o espaço de nomes ao qual pertence o nome especificado.
  • 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 de espaço de nomes * declara explicitamente que as informações do espaço de nomes devem ser ignoradas ao localizar elementos 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
O significado de combinações diferentes de cláusulas type, namespace, name e index é o seguinte:
[..], *, *[..], (..), (..)[..], (..)*, (..)*[..]
Nenhuma dessas formas especifica um nome ou espaço de nomes. O elemento de destino é localizado, portanto, ou pelo seu tipo e índice, ou somente pelo seu índice. Todas essas formas existiam antes dessa alteração e o seu comportamento não se alterou de nenhuma maneira.
NameId, NameId[..], (..)NameId, (..)NameId[..]
Todos estes formatos especificam um nome, mas nenhum espaço de nomes. O elemento de destino é localizado por espaço de nomes e nome e também por tipo e índice, se 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 no caminho é o espaço de nomes notarget.

Todas essas formas existiam antes desta alteração. 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 elementos no espaço de nomes notarget.

:*, :*[..], (..):*, (..):*[..]
Todas essas formas especificam o espaço de nomes notarget mas nenhum nome. O elemento 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 elemento de destino é localizado por espaço de nomes e também por tipo de índice, se apropriado.
*:*, *:*[..], (..)*:*, (..)*:*[..]
Nenhuma dessas formas especifica um nome ou espaço de nomes. O elemento de destino é localizado por tipo e índice ou somente por índice.
*:NameId, *:NameId[..], (..)*:NameId, (..)*:NameId[..]
Todos estes formatos especificam um nome, mas nenhum espaço de nomes. O elemento 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 elemento de destino é localizado por espaço de nomes e 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 elemento de destino é localizado por espaço de nomes e também por tipo de í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.

A utilização de referências de campo geralmente implica na procura por um elemento existente. Isso é verdadeiro para referências de campo que são os destinos de instruções SET e para as que estão nas cláusulas AS de instruções SELECT. Se o elemento requerido não existir, ele será criado.

Em todas essas situações, há diversas circunstâncias nas quais um intermediário não pode saber qual é o nome ou espaço de nomes requerido; nessas situações, 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 namespace 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 elemento existente, o novo elemento 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 elemento não é Name nem NameValue, o que indica efetivamente que o novo elemento não tem nome

      .
    • Por outro lado, se o algoritmo de designação optar por copiar o nome de algum elemento existente, o novo elemento terá tanto o seu nome como o seu espaço de nomes copiados do elemento 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 elemento 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 elemento 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 elemento 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 elementos além daqueles aos quais os campos fazem referência:
  • Cópia de árvore: novos elementos são criados por um algoritmo que utiliza uma árvore de origem como gabarito. Se o algoritmo copiar o nome de um elemento de origem para um novo elemento, 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 elementos recém-criados como valores padrão (consulte Função SELECT).

    Estes padrões podem ser derivados de nomes de elementos, nomes de colunas ou podem ser simplesmente nomes de seqüência fabricados. Se o nome for o nome de um elemento, 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 elemento recém-criado será derivado da procura do caminho, isto é, o nome será tratado como a sintaxe NameId de uma referência de campo.

Cada elemento de uma referência de campo pode conter uma cláusula de índice. 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;
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 é 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 elemento e o índice 2 refere-se ao penúltimo elemento. 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 que esperam listas (por exemplo, SELECT ou CARDINALITY).

Cada elemento 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 elementos e é possível que um elemento XML contenha ambos os atributos e outros elementos XML com o mesmo nome.

Por exemplo:
<Item Value = '1234' >
     <Value>5678</Value>
</Item>
Aqui, o elemento XML Item tem dois elementos filhos, ambos chamados Value". Os elementos filhos podem ser distinguidos utilizando-se as cláusulas de tipo: Item.(XML.Attribute)Value para selecionar o atributo e Item.(XML.Element)Value para selecionar o elemento.

Conceitos relacionados
ESQL

Tarefas relacionadas
Desenvolvendo ESQL
Acessando Várias Ocorrências Conhecidas de um Elemento