Skip to main content
Announcements
Have questions about Qlik Connect? Join us live on April 10th, at 11 AM ET: SIGN UP NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
tiagopazeto
Contributor III
Contributor III

Carga incremental com chave composta não grava todos os registros

Olá pessoal!

Inicialmente agradeço a todos, pois a partir do Manual de referência e outros post aqui da comunidade, estou alterando as cargas do Qlikview para incremental, algumas já estão funcionando. No entanto, estou com um problema que ainda não achei solução. Conto com a expertise e experiência dos amigos do grupo para isto.

 

Em resumo, as cargas funcionaram quando a chave primária é apenas um campo, e meu  problema está quando a chave é composta por quatro campos conforme script de exemplo.

 

Processo: leitura dos registros dos último quatro dias, seguindo os campos de inclusão ou alteração na base. Na sequência, concateno com o QVD já existente que possui 20GB e por fim, aplico o INNER JOIN para retirar registros excluídos.

 

Após todo o processo, o novo QVD ficou com apenas 350MB, o que está errado visto que mantenho os 134 milhões de registros na tabela. Em anexo incluí a imagem que mostra a leitura da tabela completa.

 

Obrigado pela atenção.

 

Script:
LET UltimaExec = date(ReloadTime() -4,'YYYY-MM-DD');

//1 -CARREGA DADOS DOS ÚLTIMOS DIAS
BN_PROD_GUIEVE_INC:
SQL
SELECT ID_PROD_GUIEVE ||'-'|| TIPO ||'-'|| CHAVE_AUX ||'-'|| ID_PROD_GUI AS CHAVE,
     GEVE.*
  FROM BN_PROD_GUIEVE GEVE
WHERE (to_char(DW_INC,'YYYY-MM-DD') >= '$(UltimaExec)'
    OR  to_char(DW_ALT,'YYYY-MM-DD') >= '$(UltimaExec)')
     ;

Concatenate

//2 -BASE JA CARREGADA:
LOAD *
FROM $(vQvds)\BN_PROD_GUIEVE_INC.QVD (qvd)
WHERE NOT EXISTS(CHAVE, ID_PROD_GUIEVE &'-'& TIPO &'-'& CHAVE_AUX &'-'& ID_PROD_GUI)
;

INNER JOIN

//3 -RETIRA REGISTROS EXCLUIDOS DA BASE:
SQL
SELECT  ID_PROD_GUIEVE ||'-'|| TIPO ||'-'|| CHAVE_AUX ||'-'|| ID_PROD_GUI AS CHAVE
  FROM DWUNIMED."BN_PROD_GUIEVE"
;

STORE BN_PROD_GUIEVE_INC INTO $(vQvds)\BN_PROD_GUIEVE_INC.QVD;

 

Muito Obrigado.

Tiago

Labels (1)
1 Solution

Accepted Solutions
rogerioqv
Creator II
Creator II

Olá Tiago...

Eu tive um problema parecido com um cliente... vou mostrar aqui o que eu achei como melhor solução para resolver o meu problema.

1) Nunca utilizo o Reloadtime() para comparar as datas, pois este somente grava a datahora em que o script terminou a execução. Desta forma, as alterações realizadas na sua base de dados durante a execução do script podem ficar de fora na próxima execução. Neste caso, controlo tudo pelo Let, ou seja, a ultima execução será igual ao início da execução atual. Assim, você garante que houve um dead line na sua carga;

2) Como você tem bastante registros na sua tabela, verifiquei que você faz uma leitura da tabela toda no 3 passo, embora da própria chave primária. Com o inner join, creio que você poderia otimizar este tempo da seguinte forma: caso o DB não seja estruturado, onde os registros "excluídos" realmente sejam apagados da base, o melhor seria solicitar à equipe de TI para criar uma tabela auxiliar onde a chave primária dos registros excluídos fossem gravados. Uma base bem estruturada teria uma "flag" que apontaria se o registros deveria ser ignorado ou não.

3) Propor uma carga incremental ao seu cliente de uma base onde os registros realmente são deletados é um tanto arriscado. Para as cargas incrementais a DB deve ser devidamente bem estruturada.

4) Pelo que vi do seu exemplo ele está correto, embora ache que você deveria otimizar o tempo e solicitar à TI para gerar a tabela auxiliar. Desta forma, você faz a leitura de forma diferente, com poucos dados, aos invés de ter que ler a base toda novamente.

Espero ter ajudado.

Abraços.

View solution in original post

10 Replies
nicolett_yuri

Tiago, mas o que seria "RETIRA REGISTROS EXCLUIDOS DA BASE"? Provavelmente é este o processo que esta removendo todos os seus dados. Como você esta fazendo INNER JOIN, então você esta apenas retornando os registros que estão na tabela BN_PROD_GUIEVE e que também esteja na tabela do qlikview BN_PROD_GUIEVE_INC.

Até o passo 2 esta correto, eu apenas alterarei o Where Exists da seguinte forma:

//2 -BASE JA CARREGADA:

LOAD *

FROM $(vQvds)\BN_PROD_GUIEVE_INC.QVD (qvd)

WHERE NOT EXISTS(CHAVE)


Pois a coluna CHAVE esta nas duas tabelas, então não preciso recria-la

tiagopazeto
Contributor III
Contributor III
Author

Yuri, Obrigado pela rápida resposta.

A chave não está pronta na tabela, por isso deve ser criada.
-----

Quando ao terceiro passo: RETIRA REGISTROS EXCLUIDOS DA BASE, é aqui que retira os registros, mas não deveria visto que os registros estão na base.


Para montar tudo, segui o Manual (pág 424) e posts da comunidade.

Manual:
Caso 4: Inserir, Atualizar e Excluir: O caso mais difícil de solucionar é quando os registros são excluídos da base de dados de origem entre as execuções de script.

Exemplo de Script:
Let ThisExecTime = Now();

Tabela_QV:
SQL SELECT ChavePrimária, X, Y FROM DB_TABLE
WHERE HoraModificação >= #$(HoraÚltExec)#
AND HoraModificação < #$(HoraDestaExec)#;

Concatenate LOAD ChavePrimária, X, Y FROM Arquivo.QVD
WHERE NOT EXISTS(ChavePrimária);

Inner Join SQL SELECT ChavePrimária FROM DB_TABLE;

If ScriptErrorCount = 0 then
STORE Tabela_QV INTO Arquivo.QVD;
Let HoraÚltExec = HoraDestaExec;
End If

Na real, entendo que o problema está em criar a chave no script ao invés de vir pronta da base de dados. Caso não tenha jeito, vou solicitar a adição deste campo.

Obrigado.

nicolett_yuri

Tiago, acho que você não entendeu a questão da chave.

Na sua base de dados esse campo CHAVE não existe, porém em seu qvd BN_PROD_GUIEVE_INC.QVD e a tabela que esta em memória BN_PROD_GUIEVE_INC já possuem o campo chave, desta forma basta utilizar: WHERE NOT EXISTS(CHAVE) em seu segundo passo que vai funcionar.

Ao meu ver, o terceiro passo é TOTALMENTE DESNECESSÁRIO, esse aqui: "Inner Join SQL SELECT ChavePrimária FROM DB_TABLE;" pois no segundo passo você já obteve o resultado que deseja.




tiagopazeto
Contributor III
Contributor III
Author

Yuri,

Realmente não tinha entendido a chave. Já alterado.

Quanto a segunda parte, vou ver aqui e te retorno.

Obrigado até o momento.

tiagopazeto
Contributor III
Contributor III
Author

Yuri,

Viajei durante o fim de semana e por isto respondo somente agora.

Me desculpe, mas entendo como necessário o terceiro passo, pois até onde li e entendi, caso um registro antigo da base de dados seja excluído, continuará gravado no QVD caso não seja aplicado o inner join.

No entanto, olhando por outro lado, talvez eu tenha entendido errado. Por isso peço que veja os anexos e faça um teste conforme abaixo.

Primeiro teste: Abra o excel e exclua os códigos: 1, 2 e 3, salve. Na sequência carregue o QVW. Os registros ainda serão apresentados na tabela.

Segundo teste: Descomente o inner join e carregue o QVW. Os registros serão excluídos do QVD e retirados da tabela.

Obrigado.

nicolett_yuri

Opa Tiago, no caso de uma exclusão do registro na tabela do banco de dados o terceiro passo seria necessário, mas isso ocorre em sua base de dados?

Caso não ocorra, não há motivos de utilização

tiagopazeto
Contributor III
Contributor III
Author

Yuri,

Aqui pode ocorrer exclusão de registros. Pelo menos em algumas tabelas e necessariamente nesta que a chave é composta.

Estou realizando novos testes com a alteração que fiz. Depois posto o que aconteceu.

brigado até o momento.

rogerioqv
Creator II
Creator II

Olá Tiago...

Eu tive um problema parecido com um cliente... vou mostrar aqui o que eu achei como melhor solução para resolver o meu problema.

1) Nunca utilizo o Reloadtime() para comparar as datas, pois este somente grava a datahora em que o script terminou a execução. Desta forma, as alterações realizadas na sua base de dados durante a execução do script podem ficar de fora na próxima execução. Neste caso, controlo tudo pelo Let, ou seja, a ultima execução será igual ao início da execução atual. Assim, você garante que houve um dead line na sua carga;

2) Como você tem bastante registros na sua tabela, verifiquei que você faz uma leitura da tabela toda no 3 passo, embora da própria chave primária. Com o inner join, creio que você poderia otimizar este tempo da seguinte forma: caso o DB não seja estruturado, onde os registros "excluídos" realmente sejam apagados da base, o melhor seria solicitar à equipe de TI para criar uma tabela auxiliar onde a chave primária dos registros excluídos fossem gravados. Uma base bem estruturada teria uma "flag" que apontaria se o registros deveria ser ignorado ou não.

3) Propor uma carga incremental ao seu cliente de uma base onde os registros realmente são deletados é um tanto arriscado. Para as cargas incrementais a DB deve ser devidamente bem estruturada.

4) Pelo que vi do seu exemplo ele está correto, embora ache que você deveria otimizar o tempo e solicitar à TI para gerar a tabela auxiliar. Desta forma, você faz a leitura de forma diferente, com poucos dados, aos invés de ter que ler a base toda novamente.

Espero ter ajudado.

Abraços.

nicolett_yuri

Ideia ótima da criação de FLAG dos campos excluídos, assim não precisa fazer um FULL SCAN em toda a recarga da aplicação do QV.