Criar SqlDataSet, DataSetProvider, ClientDataSet para consultas rápidas

Delphi

30/04/2012

Bom dia,
Estou precisando criar os componentes acima em tempo de execução para efetuar consultas rápidas e não ter que inserir componentes para os mesmos.

Tentei da seguinte forma mas não funcionou:

function RetCusto(vChave: string): boolean;
var
   vSQL: TSQLDataSet;
   vProv: TDataSetProvider;
   vCDS: TClientDataSet;
begin
   CriaDataSet(vSql,vProv,vCds);
   vCds.Close ;
   vSql.CommandText := select * from customiza where instrucao=:instrucao;
   vSql.parambyname(instrucao).asstring := vChave;
   vCds.open ;
   Result := (not vCds.Eof);
   vCds.free;
   vprov.free;
   vSql.free;
end;

procedure CriaDataSet(vSQL: TSQLDataSet; vProv: TDataSetProvider; vCDS: TClientDataSet);
begin
   // Cria SQLDATASET
   vSql               := TSQLDataSet.Create(nil);
   //vSql.Active        := False;
   vSql.Name          := sqlTeste;
   vSql.SQLConnection := dm.conexao;
   // Cria DATASETPROVIDER
   vProv              := TDataSetProvider.Create(nil);
   vProv.Name         := dspTeste;
   vProv.DataSet      := vSQL ;
   // Cria CLIENTDATASET
   vCDS               := TClientDataSet.Create(nil);
   //vCDS.Active        := False;
   vCDS.name          := cdsTeste;
   vCDS.ProviderName  := vProv.Name  ;
end;


Se tiverem uma idéia melhor, por favor me indiquem.
Mas o mais prático seria assim, no início da função cria os relacionamentos e no fim destrói e retorna a consulta.

att
Mario Inacio
Mario Inacio

Mario Inacio

Curtidas 0

Respostas

William

William

30/04/2012

Olá colega, vc poderia deixar código dentro de um bloco try..finally..end na função retCusto assim acaba ficando mais legível, quanto ao modo de criar a idéia é essa mesmo, se eu não me engano os conjunto de componentes tem que ter o mesmo AOwner senão da pau.
GOSTEI 0
Wilton Júnior

Wilton Júnior

30/04/2012

ola companheiro tudo bem?
Eu uso muito as ferramentas do dbexpress, veja o exemplo abaixo:
function AutoNum(campo:string):integer;
// Função para auto numeração
Var num : integer;
begin
num := 0;
with DTM do
begin
CDSAutoNum.Close;
Tab_AutoNum.ParamByName(wnomcampo).AsString := campo;
CDSAutoNum.open;

if CDSAutoNum.IsEmpty then
begin
num := 1;
CDSAutoNum.Insert;
CDSAutoNumNomCampo.AsString := campo;
CDSAutoNumAutoNum.asinteger := num;
end
else
begin
num := CDSAutoNumAutoNum.AsInteger;
num := num + 1;
CDSAutoNum.Edit;
CDSAutoNumAutoNum.AsInteger := num;
end;

CDSAutoNum.Post;
CDSAutoNum.ApplyUpdates(-1);
CDSAutoNum.Close;
end;

if num = 0 then
menerro(0)
else
Result := num;
end;


Nesse exemplo, utilizei o DTM é datamodulo nele possui: TSQLConection, para fazer a consulta, utilizei: TSQLQuery, TDataSerProvider, TClientDataSet e mais nada. Como pode notar, nesse linha Tab_AutoNum.ParamByName(wnomcampo).AsString := campo; somente passei o parametro. Tente assim quem sabe resolve.

Espero ter ajudado.
Obrigado.
Deus abençoe sua familia e vc.
GOSTEI 0
Marco Salles

Marco Salles

30/04/2012

Mario do jeito que voce esta fazendo parece que ira reclamar do DataSetProvider

se voce utilzar o Nil como Owner vc tem que utilizar o SetProvider do cds para passar o Provider

GOSTEI 0
Wijloc

Wijloc

30/04/2012

Mario do jeito que voce esta fazendo parece que ira reclamar do DataSetProvider

se voce utilzar o Nil como Owner vc tem que utilizar o SetProvider do cds para passar o Provider



exatamente o que eu estava precisando... obrigado MARCO ANTONIO
GOSTEI 0
Rodolpho Silva

Rodolpho Silva

30/04/2012

Uma boa alternativa é trabalhar somente com o ClientDataSet para extrair os dados, através da propriedade "data". A função abaixo retornar somente o "data packet" que pode ser atribuído em qualquer Cds:
function TMyBaseClass.getDataPacke(const SQL: String)t: OleVariant;
var
  dsp: TDataSetProvider;
  Cds: TClientDataSet;
  FDataSet: TSQLQuery;
begin
  Result := null;
    try
      dsp := TDataSetProvider.Create(nil);
      FDataSet: TSQLQuery.Create(nil);
      // Não esquecer de apontar o FDataSet para sua conexão...

      Cds := TClientDataSet.Create(nil);
      dsp.DataSet := FDataSet;
      Cds.SetProvider(dsp);
      Cds.Open;
      Result := Cds.Data;

    finally
      FreeAndNil(Cds);
      FreeAndNil(dsp);
      FreeAndNil(FDataset);
    end;
end;


E o uso seria...
MyCds.Data := getDataPacket('select * from clientes');
GOSTEI 0
Thiago Irrazabal

Thiago Irrazabal

30/04/2012

Boa tarde, modifiquei uma linha do teu código e a declaração da procedure CriaDataSet, ficando assim:

Declaração da procedure:
procedure CriaDataSet(var vSQL: TSQLDataSet; var vProv: TDataSetProvider;
      var vCDS: TClientDataSet);


Ficando assim dentro dela:
procedure TForm1.CriaDataSet(var vSQL: TSQLDataSet;
  var vProv: TDataSetProvider; var vCDS: TClientDataSet);
begin
   // Cria SQLDATASET
   vSql               := TSQLDataSet.Create(nil);
   //vSql.Active        := False;
   vSql.Name          := 'sqlTeste';
   vSql.SQLConnection := SQLConnection1;
   // Cria DATASETPROVIDER
   vProv              := TDataSetProvider.Create(nil);
   vProv.Name         := 'dspTeste';
   vProv.DataSet      := vSQL;
   // Cria CLIENTDATASET
   vCDS               := TClientDataSet.Create(nil);
   //vCDS.Active        := False;
   vCDS.Name          := 'cdsTeste';
   vCDS.SetProvider(vProv); //MODIFIQUEI ESSA LINHA
end;




Att,
Thiago Irrazabal de Oliveira.
GOSTEI 0
Mario Inacio

Mario Inacio

30/04/2012

Boa tarde,
A função com as mudanças propostas funciona muito bem na primeira execução, se precisar executa-la novamente ocorre o seguinte erro:

procedure CriaBase(vNome: string; var vSQL: TSQLDataSet; var vProv: TDataSetProvider; var vCDS: TClientDataSet;
                   var vDM: TSQLConnection);
begin
   vSql                    := TSQLDataSet.Create(nil);
   vSql.Name               := 'tmp_sql'+vNome;
   vSql.SQLConnection      := vDm;
   vSql.GetMetadata        := False;

   vProv                   := TDataSetProvider.Create(nil);
   vProv.Name              := 'tmp_dsp'+vNome;
   vProv.DataSet           := vSQL;

   vCDS                    := TClientDataSet.Create(nil);
   vCDS.Name               := 'tmp_cds'+vNome;
   vCDS.SetProvider(vProv);
end;


procedure ExecutaRotina;
var
   SQL1: TSQLDataSet;
   DSP1: TDataSetProvider;
   CDS1: TClientDataSet;
   i: integer;
begin
   try
      CriaBase('teste',Sql1,Dsp1,Cds1,dm.conexao);
      for i:=0 to 1 do begin
         cds1.close;
         sql1.commandtext := 'select * from produtos where codpro=:codpro';
         sql1.parambyname('codpro').asinteger := i;
         cds1.Open; // erro aqui na segunda passagem
      end;
   finally
      ExcluiBase(Sql1,Dsp1,Cds1);
   end;
end;


Nesse pequeno loop, na segunda execução do cds1.open ocorre o erro.

Erro na segunda execução do OPEN "Missing data provider or data packet
GOSTEI 0
Mario Inacio

Mario Inacio

30/04/2012

up up
GOSTEI 0
POSTAR