Fórum Traduzir mensagem do Banco clientdataset e firebird #325228

12/07/2006

0

Uso Tecnologia DbExpress com Firibird 1.5


em assunto não é novo . JA fiz uma pesquisa , mas so achei algo parecido em

http://forum.clubedelphi.net/viewtopic.php?t=47844&highlight=chave+primaria+mensagem

so que ele não disse como resolveu ??? :cry: :cry: :cry:

então venho lançar novamente esta questão

Tenho uma chave primária , e no momento que dou um apllyUpdates no Cds me retorna o erro

[b:750819b664]Field ´COMPOSICAO´ must have a value[/b:750819b664]

Gostaria de interceptar esta mensagem de erro retornada pelo Banco de Dados , para transforma-la em uma mensagem mais amigavel

O Problema é que não estou conseguindo interceptar a mensagem que vem do Banco , para trata-la

E Mais estranho que coloquei um codigo no evento [b:750819b664]OnEconcileError[/b:750819b664] , e este evento nesta situação Não é disparado :cry: :cry: :cry:

procedure TDm.CdCompReconcileError(DataSet: TCustomClientDataSet;
  E: EReconcileError; UpdateKind: TUpdateKind;
  var Action: TReconcileAction);
begin
showmessage(´Evento NÃO É DISPARADO...PORQUE ????);
end;


Não sei se é o caso mas estou usando DataModulo e o erro ocorre em outro Formulário



Marco Salles

Marco Salles

Responder

Posts

14/07/2006

Marco Salles

Pouco interresse dos amigos nesse tópico :cry: :cry: :cry: :cry:

Desde ontem so quatro visitas :evil: :evil: :evil:

E mesmo assim estas quatro visitas acho que forma minhas , vendo e relendo o tópico. :lol: :lol: :lol: :lol:


Responder

Gostei + 0

14/07/2006

Macario

Olá Marco Salles, bom dia.

Não tenho a resposta para este assunto, mas tenho interesse pelo mesmo.


Você ja tentou tratar o evento usando a variavel [b:cd4b68b69c]UpdateKind[/b:cd4b68b69c]?
E a mensagem?


Responder

Gostei + 0

14/07/2006

Marco Salles

Não tenho a resposta para este assunto, mas tenho interesse pelo mesmo.


Você ja tentou tratar o evento usando a variavel UpdateKind? E a mensagem?


a messagem vem do Banco e a principio ela não é propagada pelo ClienteDataset..

o Evento OnReconcileError nen é disparado.... É isto que esta me deixando encucado... Na hora que dou um ApllyUpdated(0) , porque este evento não esta sendo Disparado :?: :?: :?: :?: :?:


Responder

Gostei + 0

15/07/2006

Lindomar.des

Marcos,

Sou iniciante ainda nesse tipo de acesso, mas pelo que sei o evento OnReconcileError é disparado qdo ha divergencias entre as informações do registro que vc está vendo com o q está no banco. Tipo: duas pessoas alteram o preço de um mesmo produto, na hora que o ultimo gravar ocorrerá o erro. Para o que vc está tentando fazer recomendaria o evento
OnPostError do clientedataset: exmplo:

procedure TdmMProvider.CDSPostError(DataSet: TDataSet; E: EDatabaseError;
var Action: TDataAction);
begin
if (Pos(´Field value required´, e.Message) > 0) or (Pos(´must have a value´,
e.Message) > 0) then
begin
MessageBox(Application.Handle, PChar(dmDBEXMaster.sUsuario +
´, verifique os campos em vermelho. São de preenchimento obrigatório!´),
´Validação´, mb_ok + MB_ICONERROR);
Action := daAbort;
end;
end;

ainda para fazer outras validações vc pode usar o evento OnUpdateError
do DataSetProvider. exemplo:

procedure TdmMProvider.DSPUpdateError(Sender: TObject;
DataSet: TCustomClientDataSet; E: EUpdateError; UpdateKind: TUpdateKind;
var Response: TResolverResponse);
begin
//registro já cadastrado - Duplicar chave primária
if (UpdateKind = ukInsert) and (Pos(´PRIMARY or UNIQUE KEY´, e.Message) > 0)
then
MessageBox(Application.Handle, (PChar(e.Message + #13 + 13 +
dmDBEXMaster.sUsuario + ´, você está tentando gravar uma informação que´
+ ´ já existe no banco de dados!´)), ´Validação´, mb_ok +
MB_ICONERROR)
else if (UpdateKind = ukInsert) and (Pos(´insert/write´, e.Message) > 0) then
begin
MessageBox(Application.Handle, PChar(dmDBEXMaster.sUsuario +
´, você não possui permissão para incluir neste módulo!´), ´Validação´,
mb_ok + MB_ICONERROR);
(DataSet as TClientDataSet).CancelUpdates;
end
else if (UpdateKind = ukDelete) and (Pos(´delete/write´, e.Message) > 0) then
begin
MessageBox(Application.Handle, PChar(dmDBEXMaster.sUsuario +
´, você não possui permissão para excluir neste módulo!´), ´Validação´,
mb_ok + MB_ICONERROR);
(DataSet as TClientDataSet).CancelUpdates;
end
else if (UpdateKind = ukDelete) and (Pos(´empty´, e.Message) > 0) then
begin
MessageBox(Application.Handle, PChar(dmDBEXMaster.sUsuario +
´, o arquivo está vazio. Impossível exluir!´), ´Validação´,
mb_ok + MB_ICONERROR);
(DataSet as TClientDataSet).CancelUpdates;
end
//integridade referencial
else if (UpdateKind = ukDelete) and (Pos(´FOREIGN´, e.Message) > 0) or
(Pos(´Chave Estrangeira´, e.Message) > 0) then
MessageBox(Application.Handle, PChar(dmDBEXMaster.sUsuario +
´, houve violação da integridade referencial!´ + #13 + 13 +
´Você está tentando excluir um registro que está fazendo referência´
+ #13 + ´a outra tabela do banco de dados. A operação será cancelada!´),
´Integridade´, mb_ok + MB_ICONERROR)
//privilégios
else if (UpdateKind = ukModify) and (Pos(´update/write´, e.Message) > 0) then
begin
MessageBox(Application.Handle, PChar(dmDBEXMaster.sUsuario +
´, você não possui permissão para alterar neste módulo!´), ´Validação´,
mb_ok + MB_ICONERROR);
(DataSet as TClientDataSet).CancelUpdates;
end
else if (Pos(´Filed value required´, e.Message) > 0) then
begin
MessageBox(Application.Handle, PChar(dmDBEXMaster.sUsuario +
´, verifique os campos em vermelho, são de preenchimento obrigatório!´),
´Validação´, mb_ok + MB_ICONERROR);
(DataSet as TClientDataSet).CancelUpdates;
end;
Response := rrAbort;
end;


esse são alguns trechos do cod. que uso.


Responder

Gostei + 0

15/07/2006

Marco Salles

[b:053fbc84ae]Lindomar.des [/b:053fbc84ae]Obrigado pela gentileza de suas colocaçoes . Gostaria de questiona-las para que possamos aprofundar nossas duvidas e trocar nossos conhecimentos

nesse tipo de erro , usando [b:053fbc84ae]Cds , firibirid e DbExpress [/b:053fbc84ae], ate agora em nenhum desses eventos :arrow: :arrow: consegui evitar a mensagem que [b:053fbc84ae]vem do Banco[/b:053fbc84ae]

:idea: :idea:
[b:053fbc84ae]Não apresenta nada no OnReconcileError nada no .CDSPostError nada no .DSPUpdateError...Estes eventos simplesmente não são disparados[/b:053fbc84ae]


[URL=http://imageshack.us][img:053fbc84ae]http://img204.imageshack.us/img204/315/imagemlindomar1hj7.png[/img:053fbc84ae][/URL]

Consegui ate o momento apresentar , apos esta mensagem que vem do Banco , informar algo o usuário...



:lol: :lol: :lol:
Mas isto não é o que a gente quer é o que a gente precisa


[b:053fbc84ae]Lendo vários tópicos , estou inclinado a tomar duas decisoes.[/b:053fbc84ae]

Mas vou tentar com a primeira , qua deixarei aqui a idéia para que alguem possa contribuir

:idea: :idea: :idea: :idea:
[b:053fbc84ae]é a criação de uma exceção no Proprio Banco..[/b:053fbc84ae]
Isto é fácil de fazer usando O [b:053fbc84ae]IBExpert[/b:053fbc84ae]


:cry: :cry: :cry: :cry:
[b:053fbc84ae][color=darkred:053fbc84ae]o que eu não estou conseguindo é usando uma trigger , disparar esta exceção[/color:053fbc84ae][/b:053fbc84ae]

[b:053fbc84ae]A idéia seria esta .. Se ja existe um Produto com esta descrição , entaõ levanto a exceção <que fora criada por mim>[/b:053fbc84ae]

:cry: :cry: :cry:
[b:053fbc84ae]não estou conseguindo a sintase para esta trigger[/b:053fbc84ae]

Feito isto a mensagem que sera apresentada para o usuário é a mensagem definida e ela com certeza pode ser tratada no evento OnReconcileError

[b:053fbc84ae]Mas ta faltando esta Trigger...[/b:053fbc84ae] :cry: :cry: :cry:


Responder

Gostei + 0

19/07/2006

Marco Salles

A idéia seria esta .. Se ja existe um Produto com esta descrição , entaõ levanto a exceção <que fora criada por mim> [b:c6c87eab7e]não estou conseguindo a sintase para esta trigger[/b:c6c87eab7e] Feito isto a mensagem que sera apresentada para o usuário é a mensagem definida e ela com certeza pode ser tratada no evento OnReconcileError


[b:c6c87eab7e]Ainda sem solução . No Aguardo e acreditando na possibilidade de solução[/b:c6c87eab7e]


Responder

Gostei + 0

20/07/2006

Marco Salles

Pesquisando aui no forum , cheguei a esta conclusão :

AS
begin
if (exists(select 1 from composicao where DESCRICAO=new.descricao)) then
     exception ERROR_CHAVE_DUPLICADA_COMPOSICA ;
else
  begin
    insert into materia_prima (descricao,Saldo,data,Valor,Unidades)
    values
    (new.descricao,0,CURRENT_DATE,0,new.unidade);
  end
end


A ideia é gerar uma exceção , para que possa trata-la no evento OnReconcileError do ClientDataSet. É claro que por se tratar de uma chave primária , por se so o banco lança uma exceção , na hora que se tenta lançar dois produtos com a mesma descrição.. Mas a mensagem que o banco lança não é muito amigável

Porem , não sei porque , não consigo captutar este Erro para que trasmita uma mensagem mais amigável

Ainda não desisti...


Responder

Gostei + 0

20/07/2006

Emrinfo

Bom dia,

Marcos Salles, eu faco o seguinte no evento do OnReconcileError do ClientDataSet, eu testo como no exemplo abaixo:

Msg:= ´Descricao nao disponivel.´;

if (Pos(´violation of PRIMARY or UNIQUE KEY´, E.Message) > 0) or
(Pos(´attempt to store duplicate value´, E.Message) > 0) then
Begin
Msg:= ´A tentativa de insercao/edicao iria resultar em duplicidade ´ +
´de registros nesta tabela.´;
End;
if (Pos(´violation of FOREIGN KEY´, E.Message) > 0) then
Begin
Msg:= ´A tentativa de atualizacao iria causar falhas de relacionamento, ´ +
´por existirem dependentes entre as tabelas envolvidas.´;
End;

ShowMessage(E.Message + #13 + ´Descricao do erro: ´ + 13 + Msg);

Espero ter ajudado.

Evaldo.


Responder

Gostei + 0

20/07/2006

Marco Salles

Valeu emrinfo

Bom dia, Marcos Salles, eu faco o seguinte no evento do OnReconcileError do ClientDataSet, eu testo como no exemplo abaixo:


[b:6e728fab2a]O problema é que nesta situação , o evento onReconcileError não é disparado.. Então nada que tiver escrito nele , é executado...[/b:6e728fab2a]


Responder

Gostei + 0

24/07/2006

Cabelo

marcos... eu tenho uma rotina de funções e procedures que traduz as mensagens ...

segue abaixo :

Primeiro a Function Grava

Function F_Grava(l_Banco : TSQLConnection; l_sql:string) : boolean; overload;
var v_desc : TTransactionDesc;
v_query : TSQLQuery;
v_provider : TDataSetProvider;
v_client : TClientDataSet;
begin
v_query := TSQLQuery.Create(nil);
v_query.SQLConnection := l_Banco;
v_provider := TDataSetProvider.Create(nil);
v_provider.DataSet := v_query;
v_provider.Name := ´PROVIDER_GRAVA´;
v_client := TClientDataSet.Create(nil);
v_client.ProviderName := ´PROVIDER_GRAVA´;
try
begin
v_desc.TransactionID := 1;
v_desc.IsolationLevel := xilREADCOMMITTED;
l_Banco.StartTransaction(v_desc);
try
begin
result := F_query(v_query, v_client, L_sql, ´E´);
l_Banco.Commit(v_desc);
v_client.Free;
v_provider.Free;
v_query.Free;
end;
except on E:Exception do
begin
l_Banco.Rollback(v_desc);
result := false;
v_client.Free;
v_provider.Free;
v_query.Free;
P_Message_Error(E.Message);
end;
end;
end;
except
result := false;
v_client.Free;
v_provider.Free;
v_query.Free;
end;
end;


a Função F_query

function F_Query(l_Query:TSQLQuery; l_Client : TClientDataSet; l_comando:string;
l_Tipo:string) : Boolean;
var v_disable : Boolean;
begin
v_disable := l_query.ControlsDisabled;
Result := False;
if not v_disable then l_Query.DisableControls;
Try
if l_Query.Active then l_Query.Close;
if l_Client.Active then l_Client.Close;
l_Query.Sql.Clear;
l_Query.Sql.Add(l_comando);
if l_Tipo = ´E´ then
begin
l_Query.ExecSQL;
if l_Query.RowsAffected > 0 then Result := True
 else Result := False;
end
else if l_Tipo = ´O´ then
begin
l_Query.Open;
l_Client.Open;
Result := (not l_Client.isEmpty);
end;
Finally
If not v_disable then l_Query.EnableControls;
End;
end;


a procedure Message_Error

procedure P_Message_Error(l_desc : string);
begin
if Pos(´string truncation´, l_desc) > 0 then
begin
MessageDlg(´Um dos campos que vc está tentando inserir é muito grande, ´+
´ou contém caracteres especiais não suportados pelo Banco de Dados ´+
´usado neste sistema. Contate seu supervisor!´, mtError, [mbOk], 0);
end;
if Pos(´VIOLATION´, l_desc) > 0 then
begin
MessageDlg(´Registro duplicado. Favor corrigir!´, mtError, [mbOk], 0);
end;
end;


Essa Função : F_grava, deve ser usada sempre que desejar startar uma transaction no Banco..

a procedure P_Message_Error, pode ser acrescentada as mensagens que vem do banco.. desta forma funciiona perfeitamente..

espero ter ajudado..


Responder

Gostei + 0

24/07/2006

Minuto

Bem eu faço assim:

criei uma procedure:

procedure trataerro(emsg:string);
var msg:string ;
begin
  //violação de chave primaria ou campo unico
  if (Pos(´violation of PRIMARY or UNIQUE KEY´, emsg) > 0) or
     (Pos(´attempt to store duplicate value´, emsg) > 0) then
    begin
      msg:= ´A tentativa de inserção/edição iria resultar em duplicidade ´ +
            ´de registros nesta tabela.´;
            end;
            //violação de relacionamento
             if Pos(´violation of FOREIGN KEY´, emsg) > 0 then
    begin
      Msg:= ´A tentativa de atualização iria causar falhas de relacionamento, ´+
            ´por existirem dependencias entre as tabelas envolvidas.´;
     end;

           //campo Obrigatório!
             if Pos(´must have a value´, emsg) > 0 then

      Msg:= ´Este campo  não pode ser vazio ou seu valor é inválido!´;

    ShowMessage(emsg + #13 + ´Descrição do Erro: ´ + 13 + Msg); 


end; 



e depois uso o evento onposterror do CDS:

procedure TDM.cdscandidatoPostError(DataSet: TDataSet; E: EDatabaseError;
  var Action: TDataAction);
begin
trataerro(e.Message);
action := daAbort;
end;
[/code]


Responder

Gostei + 0

24/07/2006

Marco Salles

Vou testar as duas e depois eu Posto.... Mas lembre-se que estou usando Cds e meu maior problema é que nenhum evento esta sendo disparado , para que eu possa tratar a mesnagem. Mas certamente deve ter um jeito e se ainda não deu é porque nao chegou a hora .

Muito obrigado.


Responder

Gostei + 0

24/07/2006

Cabelo

Marco...

no meu exemplo... não importa qual é o componente que vc está usando... pois a gravação será feita através de um SQL...

embora deixe a aplicação um pouco mais complexa, sendo que vc precise tratar todas as rotinas manualmente, fica perfeitamente portável para qualquer banco... independente dos componentes que vc usa...

estas rotina interceptam as excessões do sistema...

INDEPENDENTEMENTE do componente usado..

um abraço..


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar