Fórum ApplyUpdates vs DBExpress (to quase voltando pro BDE) #279266

28/04/2005

0

Amigos,

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

Tadeuzao

Responder

Posts

28/04/2005

Hellsing

Opa, tudo bom ??
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]


Responder

Gostei + 0

28/04/2005

Vinicius2k

Colega,

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 é:
[b:cf05a92f43]TSQLConnection[/b:cf05a92f43] [color=red:cf05a92f43]DriverName, LibraryName, Params e VendorLib[/color:cf05a92f43], todas corretamente configuradas para acessar seu SGBD | + [b:cf05a92f43]TSQLDataSet[/b:cf05a92f43] [color=red:cf05a92f43]CommandText[/color:cf05a92f43], a instrução SQL a ser executada. [color=red:cf05a92f43]SQLConnection[/color:cf05a92f43], apontando para a SQLConnection acima. | + [b:cf05a92f43]TDataSetProvider[/b:cf05a92f43] [color=red:cf05a92f43]DataSet[/color:cf05a92f43], apontando para o SQLDataSet acima. | + [b:cf05a92f43]TClientDataSet[/b:cf05a92f43] [color=red:cf05a92f43]ProviderName[/color:cf05a92f43], apontando para o DataSetProvider acima. | + [b:cf05a92f43]TDataSource[/b:cf05a92f43] [color=red:cf05a92f43]DataSet[/color:cf05a92f43], apontando para o ClientDataSet acima.


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+


Responder

Gostei + 0

28/04/2005

Yallebr

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...


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]


Responder

Gostei + 0

28/04/2005

Tadeuzao

Olá amigos,

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.


Responder

Gostei + 0

28/04/2005

Vinicius2k

Colega,

Perdõe-me. Como vc não deu muitos detalhes sobre todos os métodos utilizados, parti do básico...

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.

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+


Responder

Gostei + 0

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

Aceitar