Como recuperar o TSQLConnection à partir do TClientDataSet ?

06/08/2004

1

Amigos,

Nesta estrutura :
TSQLConnection->TSQLDataSet -> TDataSetProvider -> TClientDataSet

Existe alguma forma de se recuperar o TSQLConnection e ler suas propriedades e/ou executar seus métodos, à partir do TClientDataSet ?

Por exemplo, se eu quiser recuperar à qual TSQLConnection está ligado um TSQLDataSet, basta que eu leia DataSet.SQLConnection...

À partir do TClientDataSet, o TDataSetProvider está ´no meio´ da leitura e não é possível ler ClientDataSet.*Provider*.DataSet.SQLConnection porque não existe no TClientDataSet uma propriedade TProvider... provavelmente porque ele pode ser remoto ( Multi-Tier )...

A propriedade ProviderName é String, eu poderia lê-la e rodar o DataModule inteiro procurando-o e encontrado, retornar seu DataSet e consequentemente sua SQLConnection, mas achei isso uma ´gambiarra´... e além disso eu teria que saber em qual DataModule está o Provider para poder procurá-lo... Alguém sugere algo diferente?

Desde já agradeço.
[]´s
Vinicius.


Responder

Posts

06/08/2004

Beppe

Vina, veja se não é viável colocar Integer(SQLConnection) na Tag do ClientDataSet. Depois recupera dali.


Responder

06/08/2004

Vinicius2k

Beppe,

O problema maior é que é para uma função... atualmente ela está +/- assim (só exemplo, existe código omitido) :
cdsApplyUpdates(aClientDataSet: TClientDataSet; aSQLConnection: TSQLConnection);
begin
  ...
  aSQLConnection.StartTransaction(TD);
  aClientDataSet.ApplyUpdates(0);
  aSQLConnection.CommitTransaction(TD);
  ...
end;

Para chamar eu preciso passar nos parametros o ClientDataSet e SQLConnection e eu queria, se possível claro, só passar o ClientDataSet...
Com a Tag com certeza é uma forma melhor, mas eu teria que ´taguear´ todos os CDS com a Tag da SQLConnection... (é isso q vc quis dizer não é?)... de qq forma eu teria q passar o DataModule no parametro para ´rodar´ e achar a SQLConnection q tem a mesma Tag do CDS...

T+
Vina.


Responder

06/08/2004

Beppe

Para chamar eu preciso passar nos parametros o ClientDataSet e SQLConnection e eu queria, se possível claro, só passar o ClientDataSet... Com a Tag com certeza é uma forma melhor, mas eu teria que ´taguear´ todos os CDS com a Tag da SQLConnection... (é isso q vc quis dizer não é?)... de qq forma eu teria q passar o DataModule no parametro para ´rodar´ e achar a SQLConnection q tem a mesma Tag do CDS...

Não, não...nada de lookup...Insira um código assim nos OnCreate´s:
ClientDataSet1.Tag := Integer(SQLConnection1);

Na sua rotina use isto TSQLConnection(aClientDataSet.Tag)


Responder

06/08/2004

Vinicius2k

:D
Blz ! It´s working fine ! :wink:

Só implementei um pouco diferente... fiz uma procedure para automatizar o processo e a chamo no OnCreate do DataModule... com 2 Loops consegui fazer o caminho inverso e ´taguear´ todos dos CDS automaticamente mesmo que eles estejam conexões diferentes...
procedure dbxAutoTagCDS(aContainer: TComponent);
var i, i2: Integer;
begin
  for i:= 0 to (aContainer.ComponentCount - 1) do
    if aContainer.Components[i] is TClientDataSet then
      for i2:= 0 to (aContainer.ComponentCount - 1) do
        if aContainer.Components[i2] is TDataSetProvider then
          if aContainer.Components[i2].Name = 
          (aContainer.Components[i] as TClientDataSet).ProviderName then
            with (aContainer.Components[i2] as TDataSetProvider) do
              (aContainer.Components[i] as TClientDataSet).Tag:= 
              Integer((DataSet as TSQLDataSet).SQLConnection);
end;


Valew a força Beppe !

Abraço.
Vina.


Responder

06/08/2004

Vinicius2k

Correção... eu estava esquecendo de testar a última classe... é necessário pq posso ter CDSs ligados à outros tipos de DataSets :
procedure dbxAutoTagCDS(aContainer: TComponent);
var i, i2: Integer;
begin
  for i:= 0 to (aContainer.ComponentCount - 1) do
    if aContainer.Components[i] is TClientDataSet then
      for i2:= 0 to (aContainer.ComponentCount - 1) do
        if aContainer.Components[i2] is TDataSetProvider then
          if aContainer.Components[i2].Name =
            (aContainer.Components[i] as TClientDataSet).ProviderName then
            with (aContainer.Components[i2] as TDataSetProvider) do
              begin
                if DataSet is TSQLQuery then
                 (aContainer.Components[i] as TClientDataSet).Tag:=
                   Integer((DataSet as TSQLQuery).SQLConnection);
                if DataSet is TSQLDataSet then
                 (aContainer.Components[i] as TClientDataSet).Tag:=
                    Integer((DataSet as TSQLDataSet).SQLConnection);
              end;
end;


T+
Vina.


Responder

07/08/2004

Rômulo Barros

Muito boa a sua solução, vina !!!! :wink:

eu, particularmente, efetuo o ´SqlConnection.Commit(Td)´ no evento Before Post de meus TClientDataSet;;;; :?

[color=red:30368ffc69]Relaxe[/color:30368ffc69] :arrow: http://www.horadocafezinho.com.br


Responder

07/08/2004

Vinicius2k

Blz U.I...

Eu pensei em abrir a transação no Before Post e commitar no After Post, mas isso pode ser ruim, pelo menos pra mim, em alguns casos como edição em várias tabelas diferentes ao mesmo tempo... Até então eu controlava a transação sempre em todos os clicks de ´salvar´, daí o código estava ficando espalhado e repetitivo...

Tenho trabalhado muito em funções para automatizar processos... com esta função ´cdsApplyUpdates´, por exemplo, com uma linha de código eu consigo efetuar a gravação, controlando a transação e exibindo mensagens de erro, inclusive o OnReconcileError (este último graças ao Beppe tbm :D)...

T+
Vina.


Responder
×
+1 DevUP
Acesso diário, +1 DevUP
Parabéns, você está investindo na sua carreira