problema clientdataset.delete
pessoal, eu escrevi o seguinte codigo
try
screen.Cursor := crSQLWait;
if Application.MessageBox(´Deseja realmente excluir este registro?´,´Mensagem do Sistema´,MB_ICONQUESTION+mb_yesno)=mryes then
begin
try
dm.ADOConnection.BeginTrans;
DataSource.DataSet.Delete;
(DataSource.DataSet as TClientDataset).ApplyUpdates(0);
dm.ADOConnection.CommitTrans;
except on
exc: exception do
begin
if Application.MessageBox(pchar(EXC.MESSAGE),´Mensagem do Sistema´,mb_iconerror+mb_ok)=mrok then
begin
if dm.ADOConnection.InTransaction then
begin
dm.ADOConnection.RollbackTrans;
end;
end;
end;
end;
end;
finally
screen.Cursor := crDefault;
end;
o sistema exibe a mensagem de erro quando a violação de chave
, mas ocorre a atualização no clientdataset
tento excluir um registro e aparece o erro, qdo dou ok, o registro some do dataset, mas permanece no banco de dados
alguem ja viu isso, como posso corrigir
abraço
try
screen.Cursor := crSQLWait;
if Application.MessageBox(´Deseja realmente excluir este registro?´,´Mensagem do Sistema´,MB_ICONQUESTION+mb_yesno)=mryes then
begin
try
dm.ADOConnection.BeginTrans;
DataSource.DataSet.Delete;
(DataSource.DataSet as TClientDataset).ApplyUpdates(0);
dm.ADOConnection.CommitTrans;
except on
exc: exception do
begin
if Application.MessageBox(pchar(EXC.MESSAGE),´Mensagem do Sistema´,mb_iconerror+mb_ok)=mrok then
begin
if dm.ADOConnection.InTransaction then
begin
dm.ADOConnection.RollbackTrans;
end;
end;
end;
end;
end;
finally
screen.Cursor := crDefault;
end;
o sistema exibe a mensagem de erro quando a violação de chave
, mas ocorre a atualização no clientdataset
tento excluir um registro e aparece o erro, qdo dou ok, o registro some do dataset, mas permanece no banco de dados
alguem ja viu isso, como posso corrigir
abraço
Arc
Curtidas 0
Respostas
Emerson Nascimento
01/09/2009
aparentemente você está tentando excluir um registro que é referenciado em outras tabelas (tipo excluir um mestre que possui detalhes).
se for algo assim, altere as propriedades do provider ou do banco de dados de modo a excluir os registros em cascata.
se for algo assim, altere as propriedades do provider ou do banco de dados de modo a excluir os registros em cascata.
GOSTEI 0
Arc
01/09/2009
emerson, eu não posso excluir em cascata
o sistema não pode excluir o registro se tiver referenciando outra tabela
o sistema não pode excluir o registro se tiver referenciando outra tabela
GOSTEI 0
Emerson Nascimento
01/09/2009
tente o método CancelUpdates.
try if Application.MessageBox(´Deseja realmente excluir este registro?´,´Mensagem do Sistema´,MB_ICONQUESTION+mb_yesno)=mryes then begin screen.Cursor := crSQLWait; try dm.ADOConnection.BeginTrans; DataSource.DataSet.Delete; (DataSource.DataSet as TClientDataset).ApplyUpdates(0); dm.ADOConnection.CommitTrans; except on exc: exception do begin (DataSource.DataSet as TClientDataset).CancelUpdates; if dm.ADOConnection.InTransaction then dm.ADOConnection.RollbackTrans; Application.MessageBox(pchar(EXC.MESSAGE),´Mensagem do Sistema´,mb_iconerror+mb_ok)=mrok end; end; end; finally screen.Cursor := crDefault; end;
GOSTEI 0
Arc
01/09/2009
infelizmente a mesma coisa
GOSTEI 0
Osocram
01/09/2009
bom isso pode ser pq a transação é controle q se faz no banco e não no ClientDataSet;
Qdo der um erro vc tem que carregar os dados novamente.
Esse é um erro que ja vi em varios lugares, inclusive eu mesmo ja o fiz muitas vezes.
O ClientDataSet grava tudo em memoria.
As transações não tem nada a ver com o ClientDataSet (diretamente).
Mesmo dando um rollback o clientDataSet continua na mesma.
No seu exemplo mesmo depois do rollBack se vc der um applyUpdate novamente ele vai tentar executar o delete.
Então o Cancel ou CancelUpdate ou até mesmo um Open ou refresh para trazer os dados novamente.
Qdo der um erro vc tem que carregar os dados novamente.
Esse é um erro que ja vi em varios lugares, inclusive eu mesmo ja o fiz muitas vezes.
O ClientDataSet grava tudo em memoria.
As transações não tem nada a ver com o ClientDataSet (diretamente).
Mesmo dando um rollback o clientDataSet continua na mesma.
No seu exemplo mesmo depois do rollBack se vc der um applyUpdate novamente ele vai tentar executar o delete.
Então o Cancel ou CancelUpdate ou até mesmo um Open ou refresh para trazer os dados novamente.
GOSTEI 0
Arc
01/09/2009
osocram,
eu fiz um tratamento de exceção no evento ReconcileError
coloquei Action:=raCancel; após a mensagem de erro, e o registro reaparece.
ficou um tanto estranho, mas foi a unica solução menos pior que encontrei
estou acostumado a fazer tudo via adoquery, usando inserts, deletes e updates.
ha muito tempo queria mexer um pouco com o clientdataset, mas nunca tive oportunidade. estou me batendo bastante com os detalhes dele, mas é isso ai
vlw
eu fiz um tratamento de exceção no evento ReconcileError
coloquei Action:=raCancel; após a mensagem de erro, e o registro reaparece.
ficou um tanto estranho, mas foi a unica solução menos pior que encontrei
estou acostumado a fazer tudo via adoquery, usando inserts, deletes e updates.
ha muito tempo queria mexer um pouco com o clientdataset, mas nunca tive oportunidade. estou me batendo bastante com os detalhes dele, mas é isso ai
vlw
GOSTEI 0
Osocram
01/09/2009
é assim mesmo... com o tempo agente vai aprendendo coisas novas
outra dica caso precise, ja que o ClientDataSet em tratamento de exceção silencioso por isso vc precisa usar o reconcilleError
vc pode fazer assim p saber qtos erros deu
erro:integer;
erro := cds.applyUpdates(0);
if erro > 0 then
showmessage(´erro´);
outra dica caso precise, ja que o ClientDataSet em tratamento de exceção silencioso por isso vc precisa usar o reconcilleError
vc pode fazer assim p saber qtos erros deu
erro:integer;
erro := cds.applyUpdates(0);
if erro > 0 then
showmessage(´erro´);
GOSTEI 0