Transação - Ler dados antes de Commitar.

Delphi

16/12/2008

Prezados,

Estou com o seguinte problema, preciso ler dados que estão dentro da transação antes dela ser confirmada.

Eu inicio uma transação, gravo os dados da tabela OrigemCliente dentro da tabela DestinoCliente, até aqui tudo bem. Depois de pegar os dados do cliente começo a gravar as contas a receber que tem deste cliente, a primeira conta a receber é gravada corretamente, a segunda gera um erro de Chave Primária Repetida.
O Campo chave da tabela DestinoRebecer não é numerado automático, então eu faço um Select max(codigo) from DestinoReceber e acrescento ao valor retornado 1, para assim gerar minha chave, mas como estou dentro de uma transação que ainda não foi confirmada o valor retornado sempre é o mesmo (zero no meu caso).

Eu estou utilizando o ADOConnection com access, tentei utilizar a propriedade IsolationLevel com ilReadUncommitted e não resolveu pois permite que transações [u:73496cc610]externas[/u:73496cc610] acessem os dados ainda não confirmados e no meu caso é a transação [u:73496cc610]interna[/u:73496cc610] que precisa dos dados.

Abaixo vou escrever o código:
while not(tabOriCliente.Eof) do
  begin
  try
  Aco.BeginTrans;
  qryDesCliente.Insert;
  qryDesCliente.FieldByName[´Codigo´].AsInteger:= tabOriCliente.FieldByName[´Codigo´].AsInteger;
  qryDesCliente.FieldByName[´Nome´].AsString:= tabOriCliente.FieldByName[´Nome´].AsString;
  qryDesCliente.FieldByName[´Endereco´].AsString:= tabOriCliente.FieldByName[´Endereco´].AsString;
  //Tem mais campos mas vamos resumir nestes.
  qryDesCliente.Post;
  
  //Localiza as Contas a Receber
  qryOriReceber.SQL.Clear;
  qryOriReceber.SQL.Add(´Select * from OriReceber where cliente = ´+tabOriCliente.FieldByName[´Codigo´].AsString);
  qryOriReceber.Open;
  
  while Not(qryOriReceber.Eof) do
    begin
qryDesReceber.Insert;
qryDesReceber.FieldByName(´Codigo´).AsInteger:= ProxNum(´DesReceber´, ´Codigo´); // <-- Aqui que ocorre o erro na segunda vez que é executado.
qryDesReceber.FieldByName(´Cliente´).AsInteger:= qryOriReceber.FieldByName(´Cliente´).AsInteger;
qryDesReceber.FieldByName(´Data´).AsDateTime:= qryOriReceber.FieldByName(´Data´).AsDateTime;
qryDesReceber.FieldByName(´Valor´).AsFloat:= qryOriReceber.FieldByName(´Valor´).AsFloat;
    //Tem mais campos mas vamos resumir nestes.
    qryDesReceber.Post;
  end;
    Aco.CommitTrans;
  except
    Aco.RollBackTrans;
raise;
  end;
end;

//Função para pegar o proximo numero
function TfrmImporta.ProxNum(sTabela, sCampo: String): Integer;
var
  aqyProxNum: TADOQuery;
begin
  aqyProxNum:= TADOQuery.Create(Application);
  aqyProxNum.Connection:= Aco; 
  
  aqyProxNum.SQL.Clear;
  aqyProxNum.SQL.Add(´select max(´+sCampo+´) as UltNum from ´+sTabela);
  if aqyProxNum.Eof then
    Result:= 1 
  else
    Result:= aqyProxNum.Fields[0].AsInteger + 1;
  //Por estar na transacao sempre e retornado 1, pois os dados da tabela ainda nao foram confirmado e estao pendentes na transacao.;
  aqyProxNum.Free;
end;


Acredito que exista uma forma de conseguir pegar o valor correto para o código, só que não sei como fazer. Caso você já tenha passado por isto ou saiba como fazer ajude a tirar minha duvida e enriqueça o fórum com seu conhecimento.

Abraços a todos vocês.


Garoto Programa

Garoto Programa

Curtidas 0

Respostas

Joaoshi

Joaoshi

16/12/2008

Colega, vê se ajuda:

Na sua função inclua a linha indicada.

//Função para pegar o proximo numero 
function TfrmImporta.ProxNum(sTabela, sCampo: String): Integer; 
var 
  aqyProxNum: TADOQuery; 
begin 
  aqyProxNum:= TADOQuery.Create(Application); 
  aqyProxNum.Connection:= Aco; 
  
  aqyProxNum.SQL.Clear; 
  aqyProxNum.SQL.Add(´select max(´+sCampo+´) as UltNum from ´+sTabela); 
  aqyProxNum.OPEN;   // INCLUIR ESTA LINHA
  if aqyProxNum.Eof then 
    Result:= 1 
  else 
    Result:= aqyProxNum.Fields[0].AsInteger + 1; 
  //Por estar na transacao sempre e retornado 1, pois os dados da tabela ainda nao foram confirmado e estao pendentes na transacao.; 
  aqyProxNum.Free; 
end; 



GOSTEI 0
Garoto Programa

Garoto Programa

16/12/2008

Pessoal me perdoem pela minha burrice.

Mas o problema estava ocorrendo porque eu havia feito referência a uma outra tabela :roll:

Vi isso logo após postar no forum.

Fazer o que né, acontece.

Ao Joaoshi meu muito obrigado pela atenção que teve com meu caso.

A todos um grande abraço e meus votos de Feliz Natal e Prospero ano novo.


GOSTEI 0
POSTAR