+5 votos
233 visitas

Em uma base Oracle, após dar um LoadAllFromQuery(TBSQLNativeControl), eu não consigo mais acessar os dados, como se estivessem bloqueados, o que não ocorre em base SQLServer.

A alteração que fiz funciona normalmente em SQL Server, mas em Oracle, quando chega na atribuição do campo "OCCLIENTESEQITEM", logo após o LoadAllFromQuery, dá o erro "Operação Inválida em um objeto fechado":

sql := TQueryObject.Create('CM_ITENS', 'A');

sql.AddFields('A', ['OCCLIENTESEQITEM SEQITEMINTEIRO']);

_sql.SetQueryObject(sql);

_itens.GetFieldsFromQuery(_sql.NativeDataSet);

_itens.AddFields('OCCLIENTESEQITEM:STRING;');

_itens.LoadAllFromQuery(_sql.NativeDataSet);
_itens.FindField('OCCLIENTESEQITEM').AsString := _sql.NativeDataSet.FieldByName('SEQITEMINTEIRO').AsString;

Fazemos este "malabarismo" com o campo "OCCLIENTESEQITEM", porque precisamos dele como string para conseguir representar valores não siginificativos no container, no banco tem que ser inteiro mesmo.

Além do erro mencionado, no Oracle não conseguimos acessar os campos do dataset durante depuração, após a execução do LoadAllFromQuery. Ex.: _sql.NativeDataSet.FieldByName('SEQITEMINTEIRO').AsString dá erro no evaluator (Ctrl + F7) do Delphi.

Vendo as propriedades desse native control, logo após a execução do LoadAllFromQuery, pude ver algumas diferenças entre os bancos (imagem em anexo), a principal foi que a propriedade FNestedDataSetClass muda de um tipo de base para outra, será que é isso que faz os dados ficarem inacessíveis? 

Estamos fazendo algo errado?

Stack do online debugger: http://desenv.benner.com.br/accessviolation/?qa=blob&qa_blobid=6117336191396093861, na linha 4208 ocorre o erro de Operação inválida em um objeto fechado.

por (21 pontos)
editado por | 233 visitas
Verifique se existe algum erro pelo online debugger. E adicione na pergunta uma stack trace do erro ocorrido.
Stack do online debugger: http://desenv.benner.com.br/accessviolation/?qa=blob&qa_blobid=6117336191396093861, na linha 4208 ocorre o erro de Operação inválida em um objeto fechado.

1 Resposta

+1 voto
Melhor resposta
Em fato, o componente TBSqlNativeControl vai apresentar este exato comportamento mesmo. A solução é não ler os campos depois que foi alcançado o final do cursor (Eof = True).

A ideia é abrir a query, ler os registros um por um até acabar e "fim". Cada vez que acionar o "Next" as informações do registro anterior foram descartadas e não podem mais ser acessadas. Também não é possível acessar as informações dos próximos registros (a não ser que se faça Next até chegar a eles). Também por isto que não é confiável usar a propriedade "RecordCount" num TBSqlNativeControl.

Este componente existe inspirado pelo comportamento dos cursores do Oracle, e os cursores do Oracle também se comportam desta maneira (quando chegou no final não é mais possível ler as informações), isto explica também pq o comportamento só é apresentado quando em Oracle, no SQLServer os comportamentos dos Cursores são simulados (para compatilidade) mas não se usufrui dos benefícios (velociadade/memória) do uso de Cursores, desta forma também não acontecem os impactos.

Lembrando que se usar o TBQuery nada disto se aplica, é uma escolha que o dev precisa fazer: se vai precisar dos benefícios oferecidos pelo TBSqlNativeControl, então vai ter que "pagar o preço".

Se não pode/quer pagar o preço, então usa o TBQuery.
por (539 pontos)
selecionada por
É melhor manter o TBSqlNativeControl pela velocidade. Então você poderia fazer a atribuição do campo com o DContainer, e não com a query.

...
_itens.LoadAllFromQuery(_sql.NativeDataSet);
_itens.FindField('OCCLIENTESEQITEM').AsString := _itens.FindField('SEQITEMINTEIRO').AsString;
Melhores May 2020
  1. henrique.muller

    18 Pontos

  2. joao.melo

    14 Pontos

  3. joseglauber

    11 Pontos

  4. SlimShady

    7 Pontos

  5. willian.metalsystem

    6 Pontos

  6. lucas.melo

    3 Pontos

  7. fluipress.luciano

    2 Pontos

  8. pajucara.wallacef

    2 Pontos

  9. jean.filho

    2 Pontos

  10. maicon.pereira

    2 Pontos

200 pontos
Melhores 2020 May 25 - 31
    433 perguntas
    476 respostas
    346 comentários
    466 usuários