dbExpress (nao consigo refreshiar depois da transação)

Delphi

08/09/2006

colegas, estou usando a rotina abaixo para incluir registros em minha tabela.

procedure TPrincipal.Btn_SalvarClick(Sender: TObject);
var 
  Transacao: TTransactionDesc;

begin


SQLDataSet2.Close;
SQLDataSet2.CommandText := ´Select GEN_ID(gen_agenda_id,1) as PROX from RDB$DATABASE´;
SQLDataSet2.Open;

Edit_Codigo.text := IntToStr(SQLDataSet2PROX.AsInteger);

ClientDataSet1.Open;
ClientDataSet1.Insert;

ClientDataSet1CODIGO.AsString         := Edit_Codigo.Text;
ClientDataSet1HORA.AsString             := hora.Text;
ClientDataSet1LOCAL.AsString            := Edit_local.Text;
ClientDataSet1ASSUNTO.AsString       := Edit_Assunto.Text;
ClientDataSet1PANFLETAGEM.AsString := Combo_panfletagem.Text;

ClientDataSet1.Post;

{*************** Transação ****************}
Transacao.TransactionID   := 1;
Transacao.IsolationLevel  := xilReadCommitted;
SQLConnection1.StartTransaction(Transacao);

if ClientDataSet1.ApplyUpdates(0) = 0 then
begin
SQLConnection1.Commit(Transacao);

// reordena DBGrid por ordem de data
ClientDataSet1.IndexFieldNames := ´DATA´;

ShowMessage(´Agenda Atualizada! Com Sucesso.´);
end
else 
begin
SQLConnection1.Rollback(Transacao);
ShowMessage(´Problemas ao salvar o registro. Alterações descartadas´);
end;
{************* Fim Transação **************}

end;

end;


essa rotina funciona beleza, o problema é que eu gostaria de atualizar os dados do meu DBGrid dinamicamente - para que caso um outro usuário na rede tenha inserido algum registro eu veja ele e nao apenas reordenando o DBGrid atraves da propriedade ´IndexFieldNames´ mas refreshiando a ´tabela + dbgrid´ - fazendo algo do tipo:


{Esse código eu uso atualmente no botao cancelar do meu form depois
de dar um cancel nos componentes.}

ClientDataSet1.Close;
ClientDataSet1.CommandText := ´SELECT * FROM Agenda order by DATA´;
ClientDataSet1.Open;


ou até mesmo:

SqlDataSet1.CommandText    := ´SELECT * FROM Agenda order by DATA´;
SqlDataSet1.ExecSQL();
ClientDataSet1.Refresh;


O Problema que eu venho encontrando é que se eu utilizar um dos dois códigos acima, a transação nao comita, mas sim vai pra esse trecho do codigo:
SQLConnection1.Rollback(Transacao);
ShowMessage(´Problemas ao salvar o registro. Alterações descartadas´);


eu queria poder fazer esa atualização ´tabela + dbgrid´, depois de realizar a transação... alguem poderia me ajudar com isso?

Componentes (dbExpress):
- SQLConnection
- SQLDataSet
- DataSetProvider
- ClientDataSet
- DataSource

Banco: FB 1.5.3


Mahdak

Mahdak

Curtidas 0

Respostas

Marco Salles

Marco Salles

08/09/2006

veja tem alguns pontos que me parece confuso:

1)usando Transação com um clientDatset voce pode deixar a cargo do proprio clientDatset que ele se encarrega disso.. Recordando o amigo vinicius2k

´Quando vc utiliza TDataSetProvider + TClientDataSet, a Midas irá se encarregar das transações. Por exemplo, ao abrir um ClientDataSet ela (a Midas) irá iniciar uma transação, solicitar os dados ao TSQLDataSet, armazenar no buffer do TClientDataSet e fechar a transação. Isto é automático e não requer sua intervenção. Sua únicas providências devem ser utilizar o método ApplyUpdates do TClientDataSet quando desejar enviar as alterações ao banco de dados (neste momento a midas irá abrir uma transação, aplicar as atualizações nos dados (se for possível) e fechar a transação) e trabalhar o evento OnReconcileError do TClientDataSet para capturar os erros durante a aplicação das atualizações. ´


2)nada tb te impede t de Controlar explicitamente a transação mesmo utilizando um TClientDataSet ... Isto tb é possivel.. Porem isto é mais uzado quando se usa varias tabelas ´aninhadas....´.. Venda , Estoque , saldo , caixa etc..

3)porem eu não entendo quando voce se refere a utilizar uma indexação , esperando que algo seje atualizado no Banco

para que caso um outro usuário na rede tenha inserido algum registro eu veja


isto no meu entendimento , não acontece .. As indexaçoes do clientDataSet são realizadas na propria máquina.. e não interferem em nada com os dados que trafegam na rede

4)
Esse código eu uso atualmente no botao cancelar do meu form depois
de dar um cancel nos componentes.

ClientDataSet1.Close; ClientDataSet1.CommandText := ´SELECT * FROM Agenda order by DATA´; ClientDataSet1.Open;


é so voce fazer isto:
ClientDataSet1.CancelUppdates;
ClientDataSet1.Close; 
ClientDataSet1.Open; 



5)
eu queria poder fazer esa atualização ´tabela + dbgrid´, depois de realizar a transação... alguem poderia me ajudar com isso?


é so abrir e fechar um clientDataSet...Os dados ja aparecerão atualizados

veja:
Por exemplo, ao abrir um ClientDataSet ela (a Midas) irá iniciar uma transação, solicitar os dados ao TSQLDataSet, armazenar no buffer do TClientDataSet


6)a idéia e trabalhar desconectado e independente o maximo possivel..

Bem , eu espero ter sido claro e ter lhe ajudado...


GOSTEI 0
Mahdak

Mahdak

08/09/2006

Marcos, valleu a mão! é que estou migrando de componentes, e ainda estou me adaptando ao dbbExpress. bom, vamos a algumas questões:

1. Agradeço, pois a minha duvida voce respondeu aqui:

4) Esse código eu uso atualmente no botao cancelar do meu form depois de dar um cancel nos componentes. [quote:124d616a65]ClientDataSet1.Close; ClientDataSet1.CommandText := ´SELECT * FROM Agenda order by DATA´; ClientDataSet1.Open;


é so voce fazer isto:
ClientDataSet1.CancelUppdates;
ClientDataSet1.Close; 
ClientDataSet1.Open; 



5)
eu queria poder fazer esa atualização ´tabela + dbgrid´, depois de realizar a transação... alguem poderia me ajudar com isso?


é so abrir e fechar um clientDataSet...Os dados ja aparecerão atualizados

veja:
Por exemplo, ao abrir um ClientDataSet ela (a Midas) irá iniciar uma transação, solicitar os dados ao TSQLDataSet, armazenar no buffer do TClientDataSet


6)a idéia e trabalhar desconectado e independente o maximo possivel..
[/quote:124d616a65]


ou seja, para atualizar meus dbgrid quando houber alterações na mesma tabela pela rede bastaria:

ClientDataSet1.Close;
ClientDataSet1.Open;


2. A questão das transações se davam pelo fato de eu trabalhar com elas nos componentes IBX, pois se eu nao fizesse algo do tipo:

Tr_Cidade = IBTransaction

if Not Tr_Cidade.InTransaction then
    Tr_Cidade.StartTransaction;
    Try
      if Tr_Cidade.InTransaction then
      Tr_Cidade.CommitRetaining
      Except
          if Tr_Cidade.InTransaction then
          Tr_Cidade.RollbackRetaining;
      end;


o commit no banco só se dava após a saida do aplicativo. realmente eu nao sabia que o dbExpress, ou melhor, o Midas, controlava as transações.

eu peguei essa informação desse tópico: http://forum.devmedia.com.br/viewtopic.php?t=58547

Então voce acha que eu nao preciso usar aquele trecho do meu código que realiza as transações? nao há necessidade, mesmo em caso de usuários usando a mesma tabela na rede ao mesmo tempo?


[quote:124d616a65=´Marco Salles´]veja tem alguns pontos que me parece confuso:

1)usando Transação com um clientDatset voce pode deixar a cargo do proprio clientDatset que ele se encarrega disso.. Recordando o amigo vinicius2k

´Quando vc utiliza TDataSetProvider + TClientDataSet, a Midas irá se encarregar das transações. Por exemplo, ao abrir um ClientDataSet ela (a Midas) irá iniciar uma transação, solicitar os dados ao TSQLDataSet, armazenar no buffer do TClientDataSet e fechar a transação. Isto é automático e não requer sua intervenção. Sua únicas providências devem ser utilizar o método ApplyUpdates do TClientDataSet quando desejar enviar as alterações ao banco de dados (neste momento a midas irá abrir uma transação, aplicar as atualizações nos dados (se for possível) e fechar a transação) e trabalhar o evento OnReconcileError do TClientDataSet para capturar os erros durante a aplicação das atualizações. ´


2)nada tb te impede t de Controlar explicitamente a transação mesmo utilizando um TClientDataSet ... Isto tb é possivel.. Porem isto é mais uzado quando se usa varias tabelas ´aninhadas....´.. Venda , Estoque , saldo , caixa etc..

3)porem eu não entendo quando voce se refere a utilizar uma indexação , esperando que algo seje atualizado no Banco

para que caso um outro usuário na rede tenha inserido algum registro eu veja


isto no meu entendimento , não acontece .. As indexaçoes do clientDataSet são realizadas na propria máquina.. e não interferem em nada com os dados que trafegam na rede
[/quote:124d616a65]


abraços!



GOSTEI 0
Mahdak

Mahdak

08/09/2006

aproveitando o tópico, alguem sabe me dizer que mensagemde erro é essa:

SQLDataset: Cursor not returned from query


o erro acontece quando vou deletar algo da tabela atravez do codigo abaixo:

SQLDataSet1.Close;
SQLDataSet1.CommandText := ´DELETE FROM AGENDA Where CODIGO = ´ + Edit_Codigo.Text;
SQLDataSet1.Open;


abraços


GOSTEI 0
Marco Salles

Marco Salles

08/09/2006

Marcos, valleu a mão! é que estou migrando de componentes, e ainda estou me adaptando ao dbbExpress. bom, vamos a algumas questões:


eu acho que voce vai admirar esta tecnologia...


Então voce acha que eu nao preciso usar aquele trecho do meu código que realiza as transações? nao há necessidade, mesmo em caso de usuários usando a mesma tabela na rede ao mesmo tempo?


eu ´acho´ que se for o caso de uma so tabela não ha necessidade.. Porque cada usuario , na sua maquina pode ir editando , alterando , excluindo e no fim dar um Applyupdates...

No caso de mais tabelas aonde uma atualização depende da outra , ai sim devemos lançar mão das atualizaçoes

Agora , ainda é cedo para dizer que todos os problemas estão resolvidos... O fato de dois usuários alterarem o mesmo campo de um registro , pode gerar situaçõe de erro ... [b:28a4a36698]Na situação de Atualizaçoes , com Transiçoes ,acho que esta situação sempre gerará erro , mas no caso de atualizaçoes com applyupdates [/b:28a4a36698], pode-se configurar os ProvidersFlags , para que a ultima atualização seje persistente no Banco... Voce ainda vai passar por esta dúvida :lol: :lol:

[b:28a4a36698]aproveitando o tópico, alguem sabe me dizer que mensagemde erro é essa: [/b:28a4a36698]

Código: SQLDataset: Cursor not returned from query o erro acontece quando vou deletar algo da tabela atravez do codigo abaixo: Código: SQLDataSet1.Close; SQLDataSet1.CommandText := ´DELETE FROM AGENDA Where CODIGO = ´ + Edit_Codigo.Text; SQLDataSet1.Open;


Voce tem associado a este SqlDataSet os componentes DataProvider e clientDataSet ?????... é bom saber que os dados do SqlDataSet é unidireceonal e , não são , por si so editávéis... Voce precisa do ´conjunto ´ , para poder editar no resultado...


GOSTEI 0
POSTAR