Histórico da Página
Composition Setup |
---|
import.css=/download/attachments/327912/newLayout.css |
Portuguese | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
FAQ: DBOs com encadeamento de EACH
Sintoma DBOs com encadeamento de EACH Causa DBOs com encadeamento de EACH Solução Sintoma: Um comando REPOSITION QUERY falha, mesmo utilizando um rowid existente e de um registro que esteja na query. Isso geralmente resulta na mensagem 11 (Não foi possível reposicionar a query). Também as telas ficam com os botões desabilitados, já que falhando o REPOSITION não haverá registro disponível, sendo assim interpretado como query sem registros. Causa: Esse problema ocorre em querys que possuem mais de uma tabela. É um erro comum inverter a ordem das tabelas, fazendo com que a tabela do DBO não seja a primeira. Veja o código abaixo, supondo que o mesmo se encontra na DBO da tabela "titulo". define query qr1 for emitente, titulo. open query qr1 for each emitente where emitente.nome-matriz = cNomeMatriz no-lock, Como o DBO pertence a tabela "titulo", o ROWID retornado será o ROWID desta tabela. Desta forma, ao tentar efetuar um REPOSITION QUERY neste DBO, nenhum registro será encontrado, visto que o REPOSITION QUERY é sempre efetuado na primeira tabela do OPEN QUERY. No entanto, o ROWID informado neste caso pertence a segunda tabela. Cannot reposition query to recid/rowid given. Solução: Para resolver esse problema, a solução é inverter a ordem das tabelas, de forma que a tabela do DBO seja a primeira no OPEN QUERY. Utilizando novamente o DBO da tabela "titulo", o exemplo anterior ficaria assim: define query qr2 for titulo, emitente. open query qr2 for each titulo no-lock where titulo.vl-saldo > 0 and titulo.dt-emissao >= daDataIni and titulo.dt-emissao <= daDataFim, each emitente no-lock where emitente.nome-matriz = cNomeMatriz and emitente.cod-emitente = titulo.cod-emitente. IMPORTANTE: Como efeito colateral dessa inversão, pode haver uma queda de performance, causada pelo aumento do número de registros lidos. Isso ocorre porque, geralmente, a segunda tabela é posta como segunda justamente porque é maior. Usando o exemplo anterior. Supondo que a tabela emitente tenha 10 registros e para cada registro de emitente existem 100 registros de titulo. Através do WHERE apenas 2 registros de emitente deverão ser selecionados. Usando a primeira opção (qr1), são lidos os 2 registros da tabela emitente e para cada um deles são lidos os 100 da tabela título, totalizando 202 registros (2 de emitente e 200 de titulo). Usando a segunda opção (qr2), são lidos os 1000 registros da tabela titulo (10 * 100), e para cada um deles é lido também o respectivo registro de emitente. Como apenas 2 emitentes atendem a condição do WHERE, os mesmos 200 registros de titulo ficarão de fato disponiveis na query, ignorando os demais 800 registros de titulo que foram lidos. Para minimizar este efeito deve-se colocar o máximo de restrições possíveis no WHERE da primeira tabela. |