BeforePost writing wrong information

1

In my Delphi application, when I break an agreement with my Client, I must update the operations data!

So I start by deleting some data from the Client, the problem happens just in this part:

procedure TDMClientes.QOperacoesBeforePost(DataSet: TDataSet);
begin
  QuebrarAcordo(DMClientes.QOperacoesBanco.AsInteger,
                DMClientes.QOperacoesCLIENTE.AsInteger,
                DMClientes.QOperacoesNROPERACAO.AsString,
                DMClientes.QOperacoesREMESSA.AsInteger,
                V_CodEvento_Quebra,true);
end;

In the code above I call a function QuebrarAcordo that is in another unit , there it works correctly:

ExecSql('UPDATE OPERACOES SET VALOR_DIVIDA = VALOR_ORIGINAL WHERE CLIENTE = XXXXXX');

Sql is executed correctly and returns to finalize the BeforePost , but a Roolback in the Database is happening!

What could be causing this roolback without warning of any error?

    
asked by anonymous 18.02.2016 / 17:15

1 answer

1

The problem is that there is not a RoolBack , let's break it down ...

You started a transaction with the database that called the BeforePost of the component, then DataSet is in Edit mode, then you called a function that performs an Update directly in the Database.

So far so good, but on returning and completing the BeforePost guess? The BeforePost will make a post (ie a commit) in your Database recording everything the component would already record!

Then, within BeforePost , before calling the function, you must Cancel the Editing state of the DataSet. Try leaving your procedure this way:

procedure TDMClientes.QOperacoesBeforePost(DataSet: TDataSet);
begin
  DMClientes.QOperacoesBanco.Cancel; //Cancela a edição que chamou o BeforePost
  QuebrarAcordo(DMClientes.QOperacoesBanco.AsInteger,
                DMClientes.QOperacoesCLIENTE.AsInteger,
                DMClientes.QOperacoesNROPERACAO.AsString,
                DMClientes.QOperacoesREMESSA.AsInteger,
                V_CodEvento_Quebra,true);
    DMClientes.QOperacoes.Refresh; //Atualiza o Componente, pois, ouve alterações
    DMClientes.QOperacoes.Edit; //Coloca novamente em Edição para finalizar outras alterações
end;

But ... ideally, instead of calling a function outside of BeforePost you run Update right there:

procedure TDMClientes.QOperacoesBeforePost(DataSet: TDataSet);
begin
  ExecSql('UPDATE OPERACOES SET VALOR_DIVIDA = VALOR_ORIGINAL WHERE CLIENTE = XXXXXX');
end;

Of course, if there is no need to call the function!

Edit:

Another more decent way to do (theoretically more correctly) would be to pass a Boolean variable true (validating that it should execute the external function), and in AfterPost check the variable and execute the function call, leaving the BeforePost Clear of additional codes Cancel , Refresh and Edit .

Explaining, when the procedure arrives at AfterPost , it means that the component has already exited the editing mode and is already updated with no additional commands! So, just validate if the variable is in True and execute the call of the external function!

    
18.02.2016 / 18:12