Árvore de páginas

FAQ: Chave duplicada no zoom.
Produto:Datasul
Ambiente:Unspecified
Versão:2
Sintoma

Nos programas de Zoom dos ThinTemplates, no momento em que a navegação ultrapassa o último registro e o programa tenta ler os próximos registros no DBO, ocorre a mensagem de erro de chave duplicada.

Causa

 

Em programas que usam browses (tipicamente programas de zoom), os registros são lidos em blocos de registros (geralmente 40).
No momento da leitura dos registros, esses são lidos numa determinada ordem, segundo o índice e as cláusulas BY presentes no comando OPEN QUERY de DBO. Ao chegar ao cliente, por meio de uma temp-table, esses registros são reordenados segundo as cláusulas presentes no OPEN QUERY do cliente. Essa reordenação, mesmo que siga os mesmos parâmetros da ordenação do DBO, pode ser ligeiramente diferente devido à quantidade de memória, parâmetros etc.
Quando o cliente ler o próximo bloco de registros, é feita um reposition no DBO para que este fique posicionado no registro que é o último registro no browse. Contudo, como a ordenação do cliente pode ser ligeiramente diferente da ordenação de DBO, o último registro do browse pode não ser o último registro lido no DBO. Isso pode fazer com que um mesmo registro seja lido novamente (causando erro de chave duplicada) se ele está no cliente antes do último registro anteriormente lido no browse.
Solução

 

A solução encontrada foi criar um campo novo, sequencial, presente na temp-table de comunicação. Com este campo novo, as cláusulas de ordenação no cliente são trocadas para usar esse campo novo, que é preenchido pelo DBO. Isso garantirá que a ordem no cliente seja exatamente igual à ordem no DBO.
Para usar essa característica, os passos abaixo devem ser seguidos:
• No DBO:
1.) No include da DBO que define a temp-table de comunicação no início da sessão "Definitions", colocar a definição do pré-processador ROW-NUM-DEFINED, contendo o valor YES. 
Por exemplo:
&GLOBAL-DEFINE ROW-NUM-DEFINED YES
2.) No mesmo include, na definição da temp-table, acrescentar o atributo RowNum, do tipo Integer, antes da definição do atributo r-Rowid. 
Por exemplo: DEFINE TEMP-TABLE {1} NO-UNDO LIKE Customer
    FIELD RowNum AS INTEGER
    FIELD r-Rowid AS ROWID.
• No Cliente (por ex. ThinTemplate):
1.) Na sessão "Definitions", colocar a definição do pré-processador ROW-NUM-DEFINED, contendo o valor YES. 
Por exemplo:
&GLOBAL-DEFINE ROW-NUM-DEFINED YES

2.) Na definição das temp-tables, definir o atributo RowNum, como inteiro, antes da definição do atributo r-Rowid. Nessa mesma definição, definir um índice primário (mas não único), contendo somente o campo RowNum. Esse índice fará com que nenhum índice seja copiado da tabela e será usado para ordenação, garantindo assim que a ordem seja a mesma de DBO. Também elimina a necessidade de colocar um BY pelo atributo RowNum no browse, o que não é possível. 
Por exemplo:
 Field RowNum as integer
 Field r-Rowid as rowid
 Index iSeq is primary RowNum.

 

Observações

 

Mais informações podem ser obtidas nos manuais de construção de DBOs e de ThinTemplates