Vi na web um monte de desenvolvedor procurando uma forma de retornar um dataset do servidor para o cliente.

Existe certamente várias soluções. Eu encontrei uma que está resolvendo para mim. É claro que a mesma deve ser utilizar da parcimônia, uma vez que retornar um grande volume de dados em um dataset pode tornar todo o seu sistema extremamente lento e ineficaz.

Basicamente o que fizemos foi:

  1. Criar uma função no servidor que recebe alguns parâmentros. Este parâmentros serão utilizados para filtrar os dados que queremos retornar. IMPORTANTE: Fuja da tentação de enviar o comando SQL através destes parâmetros. Afinal, SQL deve ser gerado APENAS no servidor.
  2. Crio uma função que vai gerar o SQL de acordo com os parâmetros passados para a função.
  3. Obtenho os dados junto ao Database;
  4. Crio um dataset para nos auxiliar na geração do XML (assim evito ter de criar o XML na mão);
  5. Copio os dados do Reader para o ClientDataSet;
  6. Retorno para o cliente o XMLData do ClientDataSet.
  7. No cliente, passo o XML para o ClientDataSet que quero exibir os dados.

É isto aí, aquele abraço e até a próxima.

function TControllerContasPagar.ContasPagarDataSet(const param: string; const param2: string = ''): TJsonString;
var
  vSQL : string;
  Reader : TDbxReader;
  cdsAux : TClientDataSet;
begin
  result := TJSONString.Create('');
  vSQL := GerarSQL(param, param2);

  Reader := GetRecords(vSQL);

  if Assigned(Reader) then begin
      cdsAux := TClientDataSet.Create(nil);
      try
        SetarCamposClientDataSet(cdsAux, vSQL);
        TDBXDataSetReader.CopyReaderToClientDataSet(Reader, cdsAux);
        result := TJSONString.Create(cdsAux.XMLData);
      finally
        FreeAndNil(Reader);
        cdsAux.Free;
     end;
  end;
end;

E a função para gerar o SQL:

function TControllerContasPagar.GerarSQL(const param, param2: string): string;
var
  vAux, vSQL, vAscDesc : string;
  i : integer;
begin
    vSQL :=
  	' SELECT cp.ID, cp.Vencimento, cp.NumDoc, cp.Descricao, cp.Valor, '+
    '        cp.Observacao, t.ID_ContaCorrente, '+
    '        cp.codFornecedor, cp.ID_Transacao, cp.ID_Empresa, '+
    '        cp.ID_PlanoContas, pc.descricao AS PlanoContas, p.nome AS Fornecedor, '+
    '        cp.ID_CentroCusto, cc.descricao AS CentroCusto, ''0'' AS Selecionar, '+
    '        IFNULL(cp.ID_FormaPgto, 0) AS id_formaPgto,'+
    '        IFNULL(cp.DocPgto, '''') AS docPgto, '+
    '        cp.DataPagamento, '+
    '        IFNULL(cp.ValorPago, 0) AS ValorPago '+
    ' FROM contas_pagar cp '+
    '   INNER JOIN plano_contas pc ON cp.id_planoContas = pc.id '+
    '   INNER JOIN pessoa p ON cp.codFornecedor  = p.id '+
    '   INNER JOIN centro_custo cc ON cp.ID_CentroCusto = cc.id '+
    '   LEFT OUTER JOIN transacoes t ON cp.ID_Transacao = t.ID '+
    ' WHERE true ';

  //-- formato url: ../ContasPagar ou ../ContasPagar/all
  if (param = '') or (lowercase(param) = 'all') then
    vSQL := vSQL + ''

  //-- formato url: ../ContasPagar/10
  //-- retorna registros com o id enviado como parametro
  else if (param <> '') and (tryStrToInt(param, i)) then
    vSQL := vSQL + ' and cp.id = ' + (param)

  //-- formato url: ../ContasPagar/last
  //-- retorna o último registro cadastrado
  else if (lowercase(param) = 'last') then
    vSQL := vSQL + ' and cp.id = (SELECT MAX(id) FROM contas_pagar)';

  //-- retorna dados de apenas uma empresa
  vAux := Helper.ObtemValorParametro('empresa', param2);
  if vAux <> '' then
    vSQL := vSQL + ' and cp.ID_Empresa = ' + (vAux);

  //-- retorna dados de apenas um determinado fornecedor
  vAux := Helper.ObtemValorParametro('fornecedor', param2);
  if vAux <> '' then
    vSQL := vSQL + ' and cp.codFornecedor = ' + (vAux);

  //-- retorna dados por periodo
    vAux := Helper.ObtemValorParametro('dataIni', param2);
  if vAux <> '' then
    vSQL := vSQL + ' and cp.vencimento >= ' + QuotedStr(vAux + ' 00:00:00');

  vAux := Helper.ObtemValorParametro('datafim', param2);
  if vAux <> '' then
    vSQL := vSQL + ' and cp.vencimento <= ' + QuotedStr(vAux + ' 23:59:59');


  vAux := Helper.ObtemValorParametro('status', param2);
  if vAux = 'quitada' then
    vSQL := vSQL + ' and cp.ID_Transacao > 0'
  else if vAux = 'aberta' then
    vSQL := vSQL + ' and cp.ID_Transacao = 0';


  //-- ordernação --------------------------------------------------------------
  //-- param: ordem=asc ou ordem=desc
  //-- campo: enviar nome do campo da ordenacao
  vAscDesc := Helper.ObtemValorParametro('ordem', param2);
  if vAscDesc <> '' then begin
    vSQL := vSQL + ' order by ';
    vAux := Helper.ObtemValorParametro('campo', param2);
    if vAux = '' then
      vAux := 'id';
    vSQL := vSQL + 'cp.' + vAux + ' ' + vAscDesc;
  end;

  //-- limite de registros retornados ------------------------------------------
  vAux := Helper.ObtemValorParametro('count', param2);
  if vAux <> '' then
    vSQL := vSQL + ' limit ' + vAux;

  result := vSQL;
end;

 

Anúncios