Um conhecimento só é válido quando compartilhado.

quarta-feira, 24 de julho de 2013

FireDAC com Firebird e CacheUpdate

Olá a todos leitores, sempre que me sobra um tempo, ando fazendo uns testes na nova suite de acesso a dados da Embarcadero o FireDAC, mas com mais de 15 anos de experiencia em programação sei que nem sempre tudo é só maravilhas.
Meus sistemas são multi-banco, hoje tenho clientes com SQL Server e alguns com Firebird, dessa forma tenho que conhecer o FireDAC testando vários bancos para saber realmente se ele irá me atender num futuro, onde o DBX deixará de avoluir, meus primeiros testes são sempre com tabelas metre-detalhe, para ter uma real noção de como a suite irá se comportar.
Os meus testes começaram com SQL Server, e logo ativei o recurso de CacheUpdate do TADQuery, pois é como trabalho hoje com DBX, nos testes simples executados tudo ok, mas quando mudei o banco de dados para Firebird, ao aplicar o ApplyUpdate(0), não persistia os dados no banco como no SQL Server.

Tudo leva a um BUG do FireDAC como os bancos Interbase e Firebird, o jeito é esperar que em futuras versões venha uma correção para essa situação, mas temporariamente ela pode ser resolvida disparando o comando "StartTransaction" pelo componente TADConnection assim:

Ao iniciar sua aplicação, e estabelecer a conexão como seu banco de dados, logo após dispare o método:

ADConnection.StartTransaction;

Pronto,  bastando este comando ao disparar o ApplyUpdates(0); será persistido as informações no seu banco de dados Firebird.

Obs: Não olhei internamente o motivo.

25/07/2013
Após alguns testes descobri uma forma mais segura e profissional de conseguir persistir os dados no banco Firebird com CacheUpdate.

   ADConnection.ApplyUpdates([ADMestre, ADDetalhe]);


Indico esta forma a ser utilizada, não a que postei anterior, pois ela deixa uma transação em aberto, essa nova forma não.

Abraço a todos.

23 comentários :

  1. 06/06/2014
    Estou utilizando o delphi xe5 update 2 estava com o mesmo problema, testei a sua ultima dica e funcionou.

    ResponderExcluir
    Respostas
    1. Obrigado pelo feedback, legal que a dia tenha sido útil.

      Excluir
  2. Olá Isaque comecei vários testes com o firedac e como sempre mestre/detalhe, estou utilizando tabelas no sqlserver com campos autoincremento, e cacheupdate ativo, porem não grava de jeito nenhum no banco, fiz um exemplo igual do Alan, onde vc até comentou com o updaterecord, já fiz de tudo.
    Como estão seus testes, evoluiu com o Firedac ?

    ResponderExcluir
    Respostas
    1. Leia meu artigo nesse link http://isaquesp.blogspot.com.br/2013/07/dbxpress-x-firedac-x-clientdataset.html

      Excluir
  3. Olá boa noite..

    podeira me ajudar como faço para atualizar o firedac no Delphixe5, pois no componente tenho FDConnection, pois quero atualizar ou instalar para ADConnection..

    pois tento compilar a conexao FDConnection a tela do celular fica tudo preto, pois faço um teste sem conexao e a tela fica perfeito aplicativo...

    poderia me ajudar meu celular é galaxy5s com a versao 4.4.2.


    obrigado

    ResponderExcluir
    Respostas
    1. A partir da versão XE5 os nomes internos foram mudados de AD para FD, não tem como usar mais AD.

      Excluir
  4. Isaque gostaria de lhe passar uma situação que estou passando com firedac veja:

    acho que vou desistir do FireDac, porque ja fiz de tudo para ele funcionar com master detail e não funciona corretamente
    se eu coloco CachedUpdade não posso da Refresh com a seguinte sql

    select a.*, b.NOME as nome_produto from ENTRADA_NOTAS_PRODUTOS a
    Left outer join PRODUTOS b on b.CODIGO_PRODUTO = A.CODIGO_PRODUTO
    where CODIGO_ENTRADA_NOTA=:CODIGO_ENTRADA_NOTA
    AND EXISTS (SELECT CODIGO_PRODUTO from produtos where CODIGO_PRODUTO= a.CODIGO_PRODUTO)


    se eu sai dessa sql e uso um campo Lookup que não recomendado para da certo na minha tabela principal usando cachedUpdate como true o componente não grava na minha tabela através da tabela master
    estou em beco sem saída com esses componente de conexão

    uma coisa que era simples no dbExpress ficou impossível no firedac que é apenas gravar os dados no banco quando desse update na tabela
    complicado

    e isso é em tabela de entrada de mercadoria o certo era só inserir os registro no banco de dados quando terminasse a operação se eu tirar cachedUpdate para false ele grava os dados antes de da posta na tabela principal então isaque como trabalhar com master detail, sendo que tenho que usar a sql com join e só pode gravar a base quando gravar na tabela principal?

    ResponderExcluir
  5. Olá pessoal
    Comecei a desenvolver um sistema para android com do Delphi XE6 utilizando o FireDac e também não grava, resolvi utilizando o seguintes passos:
    1º Coloque um componente FDTransction.
    2º Indiquei o componente FDTransction nas propriedades "Transction" e "UpdateTransction" do FDConnection.
    3º Coloquei na propriedade ChachedUpdates do FDQuery como True.

    E funcionou perfeito!

    ResponderExcluir
  6. Boa noite Isaque. Usei esta segunda formula e resolveu o problema com CachedUpdates. Delphi XE7 e Firebird 2.5.

    dm.fdqCadProdutos.Post;
    dm.FDConnection1.ApplyUpdates([dm.fdqCadProdutos]);
    //dm.fdqCadProdutos.ApplyUpdates(0);//Não pode, isto tira o último cadastro (sem usar cached - testar isto)
    ShowMessage('Cadastro Salvo!');

    Porém, ocorreu alguns outros contratempos. Se eu insistir em gravar (nome, senha, perfil - todos not null com firebird), e deixar nome em branco, e clicar em GRAVAR, ele alerta. Ai preencho nome, mas deixo a senha em branco, e ai ele permite gravar o cadastro. Isto só com os parametros de checagens do sgdb, não fiz checagens via software.

    Outro detalhe, coloquei um check (VALOR_COMPRA >= 0), e ele não me retornou erro, e nem gravou. Vou ter que mandar analisar os erros, mas fazer funcionar com cached updates. Pensei que eu já tinha resolvido esta parte...Não queria deixar sem usar cachedupdates.

    ResponderExcluir
    Respostas
    1. Lei esse post meu http://isaquesp.blogspot.com.br/2013/07/dbxpress-x-firedac-x-clientdataset.html

      Excluir
  7. Obrigado, fiquei tão interessado em ver o desempenho e usar tudo do firedac, que fiz desta forma. Até havia lido seu post, mas pensei como estou iniciando um projeto, já que falam tão bem do firedac, vou fazer tudo nele. Vi bons softwares com mysql, mssql, etc, mas no firebird deu isto. Vou testar com o TDataSetProvider no meio. No dbx algo similar a isto funcionava sem erros, e a vantagem da troca como você disse é verdade, melhor uma junta de união no encanamento, tornando mais fácil trocar a parte da ponta, do que uma luva :-D

    ResponderExcluir
  8. Tive esse problema também mais era na configuração
    Para o Updates gravar os dados na tabela configura assim
    No componente FDQuery1 deixar (CachedUpdates) true
    Agora vai no (UpdateOptions) clique no sinal de mais e procure por (UpdateTableName) e seleciona sua tabela
    Agora no botão gravar o código fica assim

    FDQuery1.Post;
    FDQuery1.ApplyUpdates();

    ResponderExcluir
    Respostas
    1. Obrigado pelo seu relato, mas esse assunto trata de master-detail, seu exemplo é de tabela simples, e ainda usado o método de abertura de table, não indicada para aplicação com banco de dados.

      Excluir
  9. Tive esse problema também mais era na configuração
    Para o Updates gravar os dados na tabela configura assim
    No componente FDQuery1 deixar (CachedUpdates) true
    Agora vai no (UpdateOptions) clique no sinal de mais e procure por (UpdateTableName) e seleciona sua tabela
    Agora no botão gravar o código fica assim

    FDQuery1.Post;
    FDQuery1.ApplyUpdates();

    ResponderExcluir
  10. Mestre Detalhe FireDAC
    Usei o exemplo do amigo do link abaixo e funcionou certinho estou usando o banco IBExpert com
    Firebird 2.5

    https://www.youtube.com/watch?v=fO99lDwa5Nc

    ResponderExcluir
  11. Ola Isaque. boa noite. estive pesquisando sobre firedac, e encontrei este post.
    No meu caso, tambem comecei a utilizar firedac em uma nova aplicação, (antes utilizada delphi 7 - dbexpress) agora delphi xe5 - firebird 2.5, FDQUERY. em 2 tabelas exclusivamente esta duplicando o registro ao gravar com applyupdate. tem alguma propriedade que pode estar errada ?. se puder ajudar de alguma forma, agradeço imensamente.
    email: dluca@bol.com.br - skype: dluca22

    ResponderExcluir
    Respostas
    1. Bom dia Nei, do meu post para cá, teve N mudanças no framework FireDAC, veja que no inicio ainda tinha AD como iniciais e hoje já é FD.
      Sempre usei dbexpress desde seu inicio, e antes já tinha passado por vários engines, mas com o dbexpress foi diferente sempre usei ele na estrutura multicamadas Query+Provider+ClientDataSet.
      Logo no inicio pensei em mudar para Firedac nativo, mas depois de analisar achei melhor mudar, mas continuar com minha estrutura existente, explico as enormes vantagens em meu post http://isaquesp.blogspot.com.br/2013/07/dbxpress-x-firedac-x-clientdataset.html

      Excluir
  12. Estou utilizando Delphi 2009 + FireDAC v8.0.5.3365! Utilizo ADConnection + ADQuery apenas para me conectar ao Firebird e MySQL. Na inclusão de um registro, após o AppyUpdates(0) quando chamo o comando RefreshRecord ou Refresh (para atualizar o(s) registro(s)) o FireDAC duplica várias vezes a inclusão do registro. Gostaria de saber se você já passou por isso e como resolver esse problema. PS: Não utilizo DSProvider + ClientDataSet!!!

    ResponderExcluir
  13. Boa Tarde Isaque.
    Parabéns pelo post.

    Sei que o seu post é antigo, mas estou usando o XE8+Firedac+Firebird e o erro que foi obtido pelo outros colegas ao tentar persistir o BD com master+detail+cachedupdates no firebird. A Mensagem é: "[FireDAC] [DatS]-16. Cannot process - no parent row. Constraint [ForeignKeyConstraint].".
    Pergunto. Tem como dizer devo colocar o codido da 2a solução? Pois não consegui gravar no banco.
    Trata-se de um erro no FIREDAC e se o meesmo já foi corrigido pela Embarcadero? Se não, não entendi porque tenho que salvar o registro mestre antes (pois entendi que com CacheUpdate isso é feito em sequencia pelo comando AppplyUpdate do TADSchemaAdapter?

    ResponderExcluir
    Respostas
    1. Boa tarde, assista esse vídeo https://www.youtube.com/watch?v=6-W5Q_hd6j0 talvez te ajude a resolver.

      Excluir
    2. Obrigado. Consegui resolver com a sua 2 dica, o AppplyUpdate (0) não funcionou no firebird.
      Mas você sabe se este erro já foi corrigido pela Embarcadero no RadStudio 10?

      Excluir
  14. Usei o seu segundo exemplo utilizando o delphi XE10 Berlin e funcionou tranquilamente, para quem estiver a fim de usar o exemplo eu usei aprovei, valeu pela dica

    ResponderExcluir

SAC Automação Delphi e Lazarus

SAC Automação Delphi e Lazarus
Assine nosso SAC Automação Delphi e Lazarus para ter suporte técnico especializado em desenvolvimento

Quem sou eu

Minha foto

Proprietário/Administrador de Empresa em TI (Tecsis Informática)
  • Autor dos projetos OpenSource ORMBr, e DBCBr
  • Autor dos componentes ACBrInstall, ACBrSped, ACBrPaf, ACBrInStore, ACBrDownload.

Total de visualizações

Postagem em destaque

ORMBr - Mapeamento objeto-relacional

Mapeamento objeto-relacional ( ou ORM, do inglês: Object-relational mapping ) é uma técnica de desenvolvimento utilizada para reduzir...

Todo os direitos reservados.. Tecnologia do Blogger.

Seguidores

Google+ Seguindores