Índice:


       

Objetivo:


       A partir da versão 12.1.23 implementamos uma melhoria na execução de relatórios do RM Reports que tende a evitar que relatórios possam gerar o que chamamos de "produto cartesiano". Esta melhoria poderá acarretar inconsistências em relatórios quando houverem bandas com mais de uma tabela e o relacionamento entre seus campos estiverem incorretos.

Detalhes da melhoria:


       Esta alteração obtém ganho de performance na execução dos relatórios. Explicaremos os cenários antes e pós alteração.

No exemplo do cenário anterior utilizaremos a seguinte estrutura no relatório;

1) - Banda pai (Detalhe1) = Ligada na tabela PFUNC

1.1) - Banda filha (SubDetalhe1)= Ligada na tabela PFDEPEND

Em cada banda utilizamos os seguintes controles (no exemplo são utilizados controles de campo da base);

1) - Banda pai:

[PFUNC.CODCOLIGADA, PFUNC.CHAPA, PFUNC.SALARIO e PPESSOA.CPF]

(informação) Neste exemplo temos um controle da tabela principal ligado a outro controle da tabela secundária (PPESSOA.CPF). 

1.1) - Banda filha:

[PFDEPEND.CODCOLIGADA e PFDEPENDE.NOME]

Filtro do relatório utilizados na banda pai do relatório.

1) - Banda pai: PFUNC.CODCOLIGADA = 1

                AND PPESSOA.CPF = '0027515458'

(informação) Neste caso temos uma parte do filtro ligado a tabela secundária da banda pai.

Quando o relatório é executado, o mecanismo de execução vai gerar duas sentenças sql’s dinamicamente baseadas nas configurações das bandas e controles.

Nesse exemplo serão geradas duas sentenças sql’s:

  1. A) - Primeira sentença: relacionada a banda pai;

SELECT PFUNC.CODCOLIGADA,
               PFUNC.CHAPA,
               PFUNC.SALARIO,
               PPESSOA.CPF
FROM PFUNC
LEFT OUTER JOIN PPESSOA (NOLOCK) ON (PFUNC.CODPESSOA = PPESSOA.CODIGO)
WHERE PFUNC.CODCOLIGADA = 1
      AND PPESSOA.CPF = '0015154515'

(informação)  Na sentença acima, o mecanismo adiciona uma clausula (Left Outer Join) para tabela PPESSOA. Isso ocorre devido ao controle "CPF" existente na banda pai pois o mesmo não existe na tabela principal da banda "PFUNC".

  1. B) - Segunda sentença: relacionada a banda filha:

SELECT PFDEPEND.CODCOLIGADA,
PFDEPENDE.NOME
FROM PFDEPEND
INNER JOIN PFUNC (NOLOCK) ON (PFUNC.CODCOLIGADA = PFDEPEND.CODCOLIGADA
                                                    AND PFUNC.CHAPA = PFDEPEND.CHAPA)
WHERE PFUNC.CODCOLIGADA = 1

(informação)  Perceba que a query acima retornará todos os dependentes de todos os funcionários da Coligada 1. Nesse caso, teremos considerado consumo de memória e performance.

Primeira sentença: Relacionada a banda pai;

SELECT PFUNC.CODCOLIGADA,
               PFUNC.CHAPA,
               PFUNC.SALARIO,
               PPESSOA.CPF
FROM PFUNC
LEFT OUTER JOIN PPESSOA (NOLOCK) ON (PFUNC.CODPESSOA = PPESSOA.CODIGO)
WHERE PFUNC.CODCOLIGADA = 1
      AND PPESSOA.CPF = '0015154515'

(informação)  Nada muda em relação à query executada atualmente.

Segunda sentença: Relacionada a banda filha;

SELECT PFDEPEND.CODCOLIGADA,
               PFDEPENDE.NOME
FROM PFDEPEND
INNER JOIN PFUNC (NOLOCK) ON (PFUNC.CODCOLIGADA = PFDEPEND.CODCOLIGADA
                                                    AND PFUNC.CHAPA = PFDEPEND.CHAPA)
LEFT OUTER JOIN PPESSOA (NOLOCK) ON (PFUNC.CODCOLIGADA = PPESSOA.CODCOLIGADA
                                                                     AND PFUNC.CODPESSOA = PPESSOA.CODIGO)
WHERE PFUNC.CODCOLIGADA = 1
      AND PPESSOA.CPF = '0015154515'

(informação)  Nesta execução, a query de Dependentes retornará somente dependentes ligados ao Funcionário com CPF "0015154515"

Em resumo com a passagem da clausula "LEFT OUTER JOIN PPESSOA" da query ligada a banda pai para a query ligada a banda filha, somente os dependentes que participam da listagem do relatório serão recuperados da base. Isso melhorará consideravelmente a performance e memória do Host.  (seleção)

       Depois do ajuste, percebermos um cenário que poderá trazer dados desnecessários no relatório, ficando a sensação de inconsistência no RM Reports.

No exemplo utilizaremos a seguinte estrutura no relatório;

1) - Banda pai (Detalhe1) = Ligada na tabela "PFUNC"

1.1) Banda filha (SubDetalhe1)= Ligada na tabela "PFDEPEND"

Em cada banda contem os seguintes controles (utilizados controles de campo da base);

1) - Banda pai:
[PFUNC.CODCOLIGADA, PFUNC.CHAPA, PFUNC.SALARIO, ABATFUN.DATA]

(informação) Neste exemplo temos um controle da tabela principal ligado a outro controle da tabela secundária (ABATFUN.DATA). 

1.1) - Banda filha: [PFDEPEND.CODCOLIGADA, PFDEPENDE.NOME]

Quando o relatório é executado, o mecanismo de execução vai gerar duas sentenças sql’s dinamicamente baseadas nas configurações das bandas e controles. Nesse caso serão geradas duas sentenças sql.

Primeira sentença: Relacionada a banda pai;

SELECT PFUNC.CODCOLIGADA,
               PFUNC.CHAPA,
               PFUNC.SALARIO,
               ABATFUN.DATA
FROM PFUNC
LEFT OUTER JOIN ABATFUN (NOLOCK) ON (PFUNC.CODCOLIGADA = ABATFUN.CODCOLIGADA
                                                                   AND PFUNC.CHAPA = ABATFUN.CHAPA)
WHERE PFUNC.CODCOLIGADA = 1
      AND ABATFUN.DATA < :DATAATUAL

(seleção) Nada muda em relação à query que será executada depois da melhoria.

Segunda sentença: Relacionada a banda filha;

SELECT PFDEPEND.CODCOLIGADA,
               PFDEPENDE.NOME
FROM PFDEPEND
INNER JOIN PFUNC (NOLOCK) ON (PFUNC.CODCOLIGADA = PFDEPEND.CODCOLIGADA
                                                    AND PFUNC.CHAPA = PFDEPEND.CHAPA)
LEFT OUTER JOIN ABATFUN (NOLOCK) ON (PFUNC.CODCOLIGADA = ABATFUN.CODCOLIGADA
                                                                    AND PFUNC.CHAPA = ABATFUN.CHAPA)
WHERE PFUNC.CODCOLIGADA = 1
      AND ABATFUN.DATA < :DATAATUAL


Neste cenário, a primeira sql, ao ser executada, retornará dados repetidos para o funcionário, visto que, existirá várias batidas para um único funcionário. Isso gera o que chamamos de "produto cartesiano". A query de dependentes retornará os dependentes ligados ao funcionário que possua batidas < que "DATAATUAL", gerando também, produto cartesiano para os dependentes.Sendo assim, ao gerar o relatório, na banda de dependentes, aparecerá vários dependentes repetidos de acordo com as batidas de um determinado funcionário.



Clique para saber mais