Fórum ApplyUpdates vs DBExpress (to quase voltando pro BDE) #279266
28/04/2005
0
Tenho uma aplicação multicamadas plataforma CORBA em Delphi5 / Oracle 9i, com clientes distribuidos em algumas cidades de SP, e banco de dados centralizado. Tenho que reescrever as aplicações para Delphi7 pois a plataforma CORBA tem me dados sérios problemas de conexão, em certos momentos o Servidor de Aplicação é fechado, sem motivo algum, simplesmente fecha ou pára de responder para os clientes, já tive consultoria da Borland que não encontrou a causa do problema, porém me indicou utilizar DCom e atualizar tudo para Delphi7.
No entanto venho testando o DBExpress, porém tenho obtido amargos resultados.
Toda a antiga aplicação servidora trabalha em cima de DataSetProvider, Querys e os bons e velhos UpdateSQL.
Como teste desenvolvi uma aplicação simples, utilizando um SQLConnection, um SimpleDataSet, um DataSource e um dbGrid. No SQLConnection setei o MultiTransaction para True.
Bom indo direto ao problema, após conectar ao banco e abrir o SimpleDataSet, eu vou ao DBGrid e faço uma alteração por exemplo no campo ´quantidade´... depois executo uma rotina que faz um StartTransaction, ApplyUpdates(-1) e Commit, como o código segue abaixo:
if not SQLConnectionX.InTransaction then begin TD.IsolationLevel := xilREADCOMMITTED; TD.TransactionID := 1; SQLConnectionX.StartTransaction(TD); try SimpleDataSet1.ApplyUpdates(-1); SQLConnectionX.Commit(TD); except on E: Exception do begin SQLConnectionX.Rollback(TD); raise Exception.Create(E.Message); end; end; end;
Ok, o Grid é atualizado com a informação nova, porém após executar um Close / Open no SimpleDataSet as atualizações são perdidas.
Após muitas tentativas descobri algo no mínimo sinistro. Quando executo um SELECT * FROM TABELA, não consigo atualizar nenhum campo da tabela como citado acima. Porém, quando utilizo um SELECT QUANTIDADE FROM TABELA, por exemplo, se for este o campo a ser alterado, a atualização é realizada com sucesso.
Mas preciso dos outros campos para visualização, mesmo que só o campo quantidade sofra alteração. Já estou entrando em desespero, pois tenho um prazo e não consigo sair de um problema ridículo como este.
Vocês tem alguma sugestão, devo utilizar DBExpress realmente, sabendo que a unica forma de atualização por ApplyUpdates seria este chulo componente SimpleDataSet? Existe algum componente mais adequado para isto? Lembrando que tenho que utilizar ApplyUpdates, pois se tiver que trocar tudo para ExecSQL, levaria muito tempo e não é viável.
Por favor me ajudem,
Grato,
Tadeu.
Tadeuzao
Curtir tópico
+ 0Posts
28/04/2005
Hellsing
Meu caro, uso o DBX dessa mesma maneira que você nos mostrou, porém com Firebird.
Entretanto, sempre que dou ´ApplyUpdates´, passo como parâmetro o número zero.
Da seguinte forma:
[b:c8e56fd9f4](bla bla)
SimpleDataSet1.ApplyUpdates(0);
(bla bla)[/b:c8e56fd9f4]
Esse número no parâmetro é o número de erros permitdo ao gravar os registros. Sempre que eu vejo exemplos com DBX, esse é o número usado (o zero). Nem sabia que podia usar um número negativo... :)
Mas tente fazer o que te falei. Se não funcionar, fale.
Abraços...
[b:c8e56fd9f4]Hellsing[/b:c8e56fd9f4]
Gostei + 0
28/04/2005
Vinicius2k
Não estou afirmando que o problema seja o SimpleDataSet, mas como vc já deve ter ´ouvido falar´, ele é, realmente, muito ruim...
O padrão recomendado para o trabalho de dados no dbExpress é:
No seu caso, vc deveria substituir seu SimpleDataSet por um TSQLDataSet e um TClientDataSet.
Vc também não deve utilizar o valor ´-1´ como parametro para o ApplyUpdates. Desta forma vc está indicando que não há limite de erros para o método. Ou seja, não importa se existirem erros, o que puder ser aplicado será.
Normalmente, ´trava-se´ para que não possa existir nenhum erro, e se ele ocorrer, volta-se a transação. Esta trava é feita com o valor ´0´ no parametro e condicionando o prosseguimento da rotina a não haver erros no ApplyUpdates.
Lembrando ainda que o ApplyUpdates não gera exceção em caso de erros o que faz com que o bloco Try..Except não surta o efeito que vc talvez espere.
Separei para vc alguns tópicos que participei sobre o assunto, se vc utilizar a pesquisa do fórum, com certeza irá encontrar mais :
http://forum.clubedelphi.net/viewtopic.php?t=51337
http://forum.clubedelphi.net/viewtopic.php?t=58829
http://forum.clubedelphi.net/viewtopic.php?t=58547
http://forum.clubedelphi.net/viewtopic.php?t=53646
http://forum.clubedelphi.net/viewtopic.php?t=46728
Sugiro que vc, antes de tudo, faça a substituição do TSimpleDataSet, feito isto ´amarre´ os ApplyUpdates de forma que só seja dado o Commit da transação caso não ocorram erros... e exiba através do OnReconcileError os erros ocorridos.
Desta forma vc estará trabalhando da forma ´ideal´ e será mais fácil detectar o problemas se eles persistirem.
T+
Gostei + 0
28/04/2005
Yallebr
So para completar.
Esse número é a quantidade de erros permitidos. -1 significa que podem acontecer ilimitados erros q será gravado.
0 = não permite erro.
-1 = Ilimitado
Eu uso [b:3e65c3a299]-1.[/b:3e65c3a299]
Gostei + 0
28/04/2005
Tadeuzao
Só gostaria de comentar que tenho conhecimento sobre o ApplyUpdates(-1), e ele não é o problema, pois utilizo o evento OnReconcileError, caso ocorra algum erro, e este erro ainda passa por um tratamento antes de ser exibido ao usuário.
Também gostaria de comentar que tenho conhecimento em relação ao SimpleDataSet vs TSQLDataSet+TDataSetProvider+TClientDataset... porém nas 2 opções acontece o mesmo problema.
O mais engraçado é que o erro que recebo no Reconcile do ClientDataset é ´tabela ou view não existe´, é mole? Na hora de abrir a DataSet não recebo erro nenhum.
Ao amigo que me recomendou utilizar FireBird, heeheh, valeu pela dica mas utilizo Oracle a muitos anos e não troco ele por nada...
O problema persiste.
Gostei + 0
28/04/2005
Vinicius2k
Perdõe-me. Como vc não deu muitos detalhes sobre todos os métodos utilizados, parti do básico...
o dbExpress tem uma ´particularidade´, que talvez possa estar originando o problema : [b:764b17a0e5]os nomes dos objetos do banco de dados precisam estar em maiúsculas. [/b:764b17a0e5]
Não existe (não conheço) documentação sobre isso, se é um bug, ou se é uma premissa para utilizar o dbExpress... Mas por experiência poderia lhe afirmar que isto é necessário.
Não seria este o problema?
T+
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)