Erro ao aplicar o Delta manualmente usando BeforUpdateRecord
Estou usando Delphi 7 + Firebird 1.5 + DbExpress.
Tenho uma query na qual faço um join e quero aplicar a cache (delta) manualmente.
Seguindo o exemplo da ClubeDelphi nº 25, descobri que tenho que utilizar o evento BeforUpdateRecord do Provider.
Fiz conforme no exemplo e a opção de exclusão funcionou normalmente, mas a opção de alteração só me retornava o erro [b:9af8697e7f]Unexpected end of command[/b:9af8697e7f].
Após exaustivas tentativas, peguei um pequeno exemplo à parte do projeto, onde tentei aplicar a cache em apenas uma tabela - ocorreu o mesmo problema - a exclusão funciona, mas a alteração da o erro acima.
Segue o código:
Com o Showmessage descobri que o comando esta sendo enviado assim:
[i:9af8697e7f]UPDATE FILIAL SET NOME = ´TESTE 1´ WHERE CODIGO =[/i:9af8697e7f]
Ou seja, dá o erro porque esta faltando a informação do DeltaDS.FieldByName(´CODIGO´).AsString.
Na exclusão fiz o teste e ele me retorna certinho:
[i:9af8697e7f]DELETE FROM FILIAL WHERE CODIGO = 1[/i:9af8697e7f]
Pergunto: Porque não tenho o campo CODIGO no Delta ? Ou porque esta vindo vazio ?
Obrigado,
Marcello
Tenho uma query na qual faço um join e quero aplicar a cache (delta) manualmente.
Seguindo o exemplo da ClubeDelphi nº 25, descobri que tenho que utilizar o evento BeforUpdateRecord do Provider.
Fiz conforme no exemplo e a opção de exclusão funcionou normalmente, mas a opção de alteração só me retornava o erro [b:9af8697e7f]Unexpected end of command[/b:9af8697e7f].
Após exaustivas tentativas, peguei um pequeno exemplo à parte do projeto, onde tentei aplicar a cache em apenas uma tabela - ocorreu o mesmo problema - a exclusão funciona, mas a alteração da o erro acima.
Segue o código:
procedure TDataModule1.DSPFilialBeforeUpdateRecord(Sender: TObject; SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var Applied: Boolean); begin case UpdateKind of ukDelete: begin ShowMessage(´DELETE FROM FILIAL WHERE CODIGO = ´ + DeltaDS.FieldByName(´CODIGO´).AsString); SQLConnect.ExecuteDirect(´DELETE FROM FILIAL WHERE CODIGO = ´ + DeltaDS.FieldByName(´CODIGO´).AsString); end; ukModify: begin ShowMessage(´UPDATE FILIAL SET NOME = ´ + QuotedStr(DeltaDS.FieldByName(´NOME´).AsString) + ´ WHERE CODIGO = ´ + DeltaDS.FieldByName(´CODIGO´).AsString); SQLConnect.ExecuteDirect(´UPDATE FILIAL SET NOME = ´ + QuotedStr(DeltaDS.FieldByName(´NOME´).AsString) + ´ WHERE CODIGO = ´ + DeltaDS.FieldByName(´CODIGO´).AsString); end; end; //case //Diz ao DatasetProvider que já foi aplicada a cache Applied:= True; end;
Com o Showmessage descobri que o comando esta sendo enviado assim:
[i:9af8697e7f]UPDATE FILIAL SET NOME = ´TESTE 1´ WHERE CODIGO =[/i:9af8697e7f]
Ou seja, dá o erro porque esta faltando a informação do DeltaDS.FieldByName(´CODIGO´).AsString.
Na exclusão fiz o teste e ele me retorna certinho:
[i:9af8697e7f]DELETE FROM FILIAL WHERE CODIGO = 1[/i:9af8697e7f]
Pergunto: Porque não tenho o campo CODIGO no Delta ? Ou porque esta vindo vazio ?
Obrigado,
Marcello
Marcello
Curtidas 0
Respostas
Night_man
26/07/2006
jah passei por isso..
o valor do campo quando esta no DeltaDS eh <>.
assim, se for uma insercao esta em NewValue
DeltaDS.FieldByName(´CODIGO´).NewValue,
numa edicao do campo pode ser em dois lugar
o novo valor esta em NewValue
DeltaDS.FieldByName(´CODIGO´).NewValue
e o valor anterior em
DeltaDS.FieldByName(´CODIGO´).OldValue
como codigo nao foi alterado utilize
DeltaDS.FieldByName(´CODIGO´).OldValue
parece estranho a primeira vista mas depois o cara entende....
o valor do campo quando esta no DeltaDS eh <>.
assim, se for uma insercao esta em NewValue
DeltaDS.FieldByName(´CODIGO´).NewValue,
numa edicao do campo pode ser em dois lugar
o novo valor esta em NewValue
DeltaDS.FieldByName(´CODIGO´).NewValue
e o valor anterior em
DeltaDS.FieldByName(´CODIGO´).OldValue
como codigo nao foi alterado utilize
DeltaDS.FieldByName(´CODIGO´).OldValue
parece estranho a primeira vista mas depois o cara entende....
GOSTEI 0
Marcello
26/07/2006
Cara, é isso aí, da certinho.
Tem outro jeito que um amigo me passou também: usar ao invés do DeltaDs o SourceDs.
Obrigado!
Marcello.
Tem outro jeito que um amigo me passou também: usar ao invés do DeltaDs o SourceDs.
Obrigado!
Marcello.
GOSTEI 0
Night_man
26/07/2006
assim o SorceDS eh todo o dataset que originou a alteracao, o DeltaDS eh um dataset somente com o registro que esta sendo alterado/excluido/inserido
GOSTEI 0
Marcello
26/07/2006
:cry: O problema agora é outro: Tenho uma tabela com uns 10 campos - a exclusão e a inserção estão OK, mas a alteração ta pegando, pois como saber dos 10 campos qual foi alterado para criar a SQL de Update ?
Para o exemplo que citei anteriormente, tinha somente 2 campos, mas neste eu não estou sabendo como fazer ?
Obrigado,
Marcello.
Para o exemplo que citei anteriormente, tinha somente 2 campos, mas neste eu não estou sabendo como fazer ?
Obrigado,
Marcello.
GOSTEI 0
Night_man
26/07/2006
o update kind te diz qual registro esta sendo alterado (ukmodify), excluido (ukdelete). inserido (ukinsert)
GOSTEI 0
Marcello
26/07/2006
OK. A minha dúvida é qual o campo(s) do registro foi alterado ? Por exemplo, suponha que eu tenha os seguintes campos em um registro:
CODIGO, NOME, PRECO
e quero alterar apenas o preco, ou apenas o nome, como eu monto a rotina dentro do ukmodify ?
Se eu alterar o PRECO, o delta não traz nada para o NOME e vice-versa, então como fazer ?
CODIGO, NOME, PRECO
e quero alterar apenas o preco, ou apenas o nome, como eu monto a rotina dentro do ukmodify ?
Se eu alterar o PRECO, o delta não traz nada para o NOME e vice-versa, então como fazer ?
GOSTEI 0
Night_man
26/07/2006
eh oq eu de disse antes o negocio dos newvalue e oldvalue
quando o registro eh alterado ele fica com valor nos dois.
valos dizer que tenha dois campos CODIGO e DESCRICAO
CODIGO = 12 e DESCRICAO = ´Teste´
depois da alteracao ficou
CODIGO = 12 e DESCRICAO = ´testando´
quando chegar no update record vai estar assim
FieldByName(´CODIGO´).NewValue = unassigned
FieldByName(´CODIGO´).OldValue = 12
FieldByName(DESCRICAO´).NewValue = ´testando´
FieldByName(DESCRICAO´).OldValue = ´Teste´
ou seja se NewValue <> unassigned eh pq aquele campo fo alterado
quando o registro eh alterado ele fica com valor nos dois.
valos dizer que tenha dois campos CODIGO e DESCRICAO
CODIGO = 12 e DESCRICAO = ´Teste´
depois da alteracao ficou
CODIGO = 12 e DESCRICAO = ´testando´
quando chegar no update record vai estar assim
FieldByName(´CODIGO´).NewValue = unassigned
FieldByName(´CODIGO´).OldValue = 12
FieldByName(DESCRICAO´).NewValue = ´testando´
FieldByName(DESCRICAO´).OldValue = ´Teste´
ou seja se NewValue <> unassigned eh pq aquele campo fo alterado
GOSTEI 0
Marcello
26/07/2006
Então, para o caso que eu citei - COD_PROD, NOME_PROD E PRECO_VEND, ficaria assim ?
Ou seja, eu teria que testar campo a campo para ver se teve alteração e mandar o comando ?
ukModify: begin If DeltaDS.FieldByName(´NOME_PROD´).NewValue <> Unassigned then SQLConnect.ExecuteDirect(´UPDATE PRODUTOS SET NOME_PROD = ´ + QuotedStr(DeltaDS.FieldByName(´NOME_PROD´).AsString)+ ´ WHERE COD_PROD = ´ + SourceDS.FieldByName(´COD_PROD´).AsString); If DeltaDS.FieldByName(´PRECO_VEND´).NewValue <> Unassigned then SQLConnect.ExecuteDirect(´UPDATE PRODUTOS SET PRECO_VEND = ´ + DeltaDS.FieldByName(´PRECO_VEND´).AsString+ ´ WHERE COD_PROD = ´ + SourceDS.FieldByName(´COD_PROD´).AsString); end;
Ou seja, eu teria que testar campo a campo para ver se teve alteração e mandar o comando ?
GOSTEI 0