O documento explica como GeneXus pode combinar consultas associadas a fórmulas com outras consultas para gerar sentenças otimizadas. Também descreve como atributos definidos como fórmulas globais são virtuais e não campos físicos, mas têm uma tabela associada para contexto. Além disso, detalha como fórmulas horizontais podem envolver atributos de tabelas relacionadas.
2. 98
Quando definirmos uma fórmula, GeneXus pode combinar a consulta / cálculo
associada a fórmula com a consulta na qual a fórmula está presente e assim
gerar sentenças otimizadas.
4. 100
Como explicamos neste slide, os atributos definidos como fórmula global, não são
criados como campos físico em tabelas, dizemos que são atributos virtuais.
Todavia, dizemos que tem uma tabela “associada” ou tabela “base”, para conhecer
o contexto na qual foi definida, e contar com esse contexto do momento de
disparar o cálculo correspondente onde for referenciado.
6. 102
Na definição de um atributo como fórmula horizontal, é possível envolver atributos
pertencentes a tabela associada ao atributo que a fórmula está sendo definida e
a sua tabela estendida.
No exemplo, ao definir que o atributo CustomerBalance é fórmula, o mesmo deixará
de existir como campo físico da tabela CUSTOMER.
Diremos a partir desse momento CustomerBalance é um atributo virtual e que sua
tabela “base ou associada” será CUSTOMER, já que se fosse armazenar dito atributo
novamente (seja porque o analista definiu que deixa de ser fórmula ou que é fórmula
redundante) seria criado como atributo físico na tabela CUSTOMER.
O tipo de cálculo desta fórmula definida é horizontal, já que consiste em uma
expressão aritmética; portanto os atributos que podem ser referenciado na definição
desta fórmula são os pertencentes a tabela CUSTOMER (tanto os armazenados
como fórmulas) e sua tabela estendida.
7. 103
Neste exemplo o atributo InvoiceDetailAmount foi definido como fórmula global
também. Isto é, utilizando o editor de fórmulas, foi associado um cálculo a este
atributo e o mesmo passará a ser um atributo virtual.
A tabela associada ao atributo InvoiceDetailAmount será INVOICEDETAIL, caso dito
atributo for armazenado novamente, será criado em dita tabela física.
Como podemos observar a fórmula definida cai na classificação de horizontal, já que
consiste em 2 expressões aritméticas condicionais. Os atributos envolvidos na
definição da fórmula pertencem a tabela INVOICEDETAIL ou a sua tabela estendida.
8. 104
No exemplo os atributos InvoiceDetail e InvoiceAmount foram definidos como fórmulas globais, já
que utilizando o editor de fórmulas foi definido uma fórmula para cada um destes atributos (os
passando a ser atributos virtuais).
Visto que as fórmulas definidas são Count e Sum respectivamente, em ambos casos se trata de
fórmulas Aggregate.
A tabela associada a ambos atributos fórmula é INVOICE, já que caso estes atributos estivesses
armazenados, seriam criados em dita tabela física.
As fórmulas Aggregate não possuem somente uma tabela base associada (como todas as
fórmulas), mas também envolvem uma tabela a ser navegada.
A tabela a ser navegada numa fórmula Aggregate, é a tabela que será navegada para realizar o
cálculo. GeneXus inferi qual a tabela a ser navegada por uma fórmula Aggregate, pelos atributos
envolvidos na definição da fórmula. Em nosso exemplo, a tabela a ser navegada em ambas
fórmulas Aggregate é INVOICEDETAIL, já que tanto na definição de Sum como Count, temos
referenciado a um único atributo associado a INVOICEDETAIL.
Quando definirmos uma fórmula Aggregate, já temos conhecimento de qual tabela pretendemos
navegar para efetuar o cálculo. Os atributos que poderemos referenciar na definição de uma
fórmula Aggregate deverão pertencer a tabela a ser navegada e sua tabela estendida + a tabela
associada ao atributo que está sendo definido como fórmula e sua tabela estendida. De
envolver numa fórmula Aggregate atributos que não pertençam a este contexto mencionado, um
error será mostrado na listagem de navegação correspondente.
Por último, havendo atributos em comum (com o mesmo nome) nas tabelas envolvidas na
definição de uma fórmula, GeneXus aplicará essa relação (isto é, um filtro automático por
igualdade pelos atributos com o mesmo nome). Isto é o que acontece neste 2 exemplos, que
GeneXus conta e soma as linhas relacionadas a seus cabeçalhos (ao somar e contar, aplica
automaticamente o filtro INVOICEDETAIL.InvoiceId = INVOICE.InvoiceId ).
9. 105
Sintaxe completa de Sum, Count, Average:
Sum | Count | Average(Expressão, [Condição Explícita, Valor por Default]) [if Condição Disparo];
Nos 2 exemplos de fórmulas Sum e Count que vimos, somente definimos o parâmetro obrigatório,
a expressão a ser somada o contada (que num caso consistiu num atributo armazenado e no outro
caso num atributo fórmula). Também dita expressão poderia envolver constantes e/ou funções.
Vimos que GeneXus determina condições de filtro implícitas ao realizar ao soma, conta ou média/
Também poderíamos ter definido condições de filtro explícitas e no caso de fazê-las, GeneXus
levará ambas em consideração: implícitas + explícitas.
De forma opcional é possível definir um valor por default a ser retornado quando não são
encontrados registros para contar, somar, ou média.
Da mesma forma que todas as fórmulas, estas também permitem incluir condição de disparo.
Por último, vale mencionar uma exceção e é em particular nas fórmulas Count, o primeiro
parâmetro deve corresponder a um atributo e não a uma expressão. Pode referenciar qualquer
atributo da tabela na qual se quer contar registros (que cumpram com condições explícitas e/ou
implícitas).
10. 106
Modificamos o desenho das transações para que ao invés de representar que cada produto
possui um preço único, representamos que cada produto tem uma lista de preços de acordo
com uma data de alteração dos mesmos.
Ao efetuar esta mudança, o atributo ProductPriceListPrice não poderá estar presente no
segundo nível da transação Invoice. Por que? Porque o novo desenho estará representando
que um produto não vai ter um preço único, mas sim muitos: um para cada data da alteração
do preço do mesmo. Portanto um produto numa linha de uma fatura, teremos que “buscar” o
preço vigente do mesmo, considerando a data da fatura.
Lembre que os atributos que podem ser inferidos em determinado nível de uma transação,
são os que pertencem a tabela estendida da tabela base associada ao nível em questão.
Neste exemplo, a tabela estendida da tabela INVOICEDETAIL, não inclui a tabela
PRODUCTPRICELIST (naquela que o atributo esteja ProductPriceListPrice):
portanto no nível Detail da transação Invoice (associado a tabela INVOICEDETAIL) não é
possível inferir o atributo ProductPriceListPrice (armazenado na tabela
PRODUCTPRICELIST).
11. 107
O que ocorre se deixarmos o atributo ProductPriceListPrice no nível Detail transação
Invoice? Como não pode ser inferido, então GeneXus não terá outra opção que armazená-lo
na tabela INVOICEDETAIL e este atributo secundário já estará em outra tabela
(PRODUCTPRICELIST). Como resultado é um modelo de dados não normalizado, e
mostrará o error ao querer reorganizar a base de dados.
E como fazemos para mostrar em cada linha da factura, o preço vigente do produto da
mesma? De todos os preços correspondentes ao produto de una linha, qual queremos
recuperar? Evidentemente, de todos os preços que tenham data menor ou igual a data da
fatura, queremos aquele que tenha data maior.
Procedemos então a criar no nível Detail da transação Invoice, um novo atributo de nome
InvoiceDetailProductPrice, ao qual o definiremos como fórmula global e portanto será um
atributo virtual.
A dito atributo vamos associar a fórmula Max:
GeneXus infere a tabela a ser navegada pelo último parâmetro da fórmula (o atributo de
retorno).
Como já se foi explicado, os atributos que poderemos referenciar na definição de uma
fórmula Aggregate deverão pertencer a tabela a ser navegada e sua tabela estendida + a
tabela associada ao atributo definido como fórmula e sua tabela estendida. Envolvendo
atributos que não pertençam neste contexto mencionado, um error é mostrado na listagem
de navegaçã correspondente.
GeneXus considera o momento de efetuar a busca a condição explícita de filtro + as
condições implícitas detectadas.
A fórmula Min é totalmente análoga a Max, com uma única diferença de que ao encontrar
um conjunto de registros que cumpram com as condições, será selecionado aquele registro
que tenha valor mínimo para o atributo indicado no primeiro parâmetro e retorne o valor de
retorno indicado no último parâmetro.
A fórmula Find por sua vez, também permite buscar um registro que cumpra com certas
condições, contudo se ter mais de 1 registro que cumpra com elas, a fórmula devolverá o
atributo de retorno correspondente ao primeiro registro encontrado (sem maximizar nem
minimizar um valor no conjunto de registros que cumpram com as condições). A sintaxe Find
é:
Find (Expressão de retorno, [Condição explícita], [Valor por default) [if Condição de
disparo]
Observar que a expressão de retorno neste caso se escreve no primeiro parâmetro da