Copiando estrutura e dados de um DBXReader para ClientDataSet – DataSnap 2010

Categories:DelphiTags: , ,

Aqueles que estão utilizando DataSnap 2010 passam a utilizar o DBXFramework, o qual recomendo muito para operações onde não existe a necessidade de expor e navegação bi-direcional.

Existem casos onde será necessário copiar a estrutura e os dados de um DBXReader para ClientDataSet ou Params, pensando nisso no Delphi foi criada a unit DBXDBReaders.pas que traz algumas classes que permite essa operação.

A classe TDBXDataSetReader possui dois método que permitem copiar para um ClientDataSet já existente ou retorna um novo ClientDataSet, veja o exemplo abaixo.

var
  Reader: TDBXReader;
  DepClient: TDepartmentClient;
begin
  DepClient := TDepartmentClient.Create(DMClientContainer.MyDSServer.DBXConnection, False);

  try
    Reader := DepClient.GetDepartmentsOrderBy;

    try
      if Assigned(Reader) then
      begin
        TDBXDataSetReader.CopyReaderToClientDataSet(Reader, DMClientContainer.CDSCopy);
      end;
    finally
      FreeAndNil(Reader);
    end;

  finally
    DepClient.Free;
  end;

O ClientDataSet CDSCopy já existe e é parte do DataModule DMClientContainer, caso o ClientDataSet não existe, utilizar o método TDBXDataSetReader.ToClientDataSet e esta irá retornar um novo ClientDataSet.

Meus exemplos sobre DataSnap 2010 foram atualizados e você pode efetuar o download aqui.

Posts relacionados

18 Responses to Copiando estrutura e dados de um DBXReader para ClientDataSet – DataSnap 2010

  1. Responder Rodrigo Carvalho says:

    Andreano, muito legal estes posts sobre DataSnap. Tenho aprendido bastante com eles e engatinhado na tecnologia, meio aos trancos e barrancos devido a deficiencia de material para estudo (principalmente em português) mas tá indo.rsrs… Tenho uma dúvida que gostaria de compartilhar aki no seu blog. Quando uso o método toClientDataSet ele trunca os campos do Reader, você sabe como posso resolver isso? Ex: Tenho um campo no Reader com 150 caracteres, no reader legal tenho os 150 depois q converto, nos novos campos do clientdataset ele armazena apenas os 20 primeiros caracteres. Já observei que 20 é o número padrão quando criamos um datasetfiels do tipo string… tem algo haver?
    Grande abraço.

    • Responder Andreano Lanusse says:

      Oi Rodrigo,

      obrigado por visitar o blog e bom saber que estas aprendendo, estamos cada vez mais trazendo materiais em português.

      Sobre o seu problema, o seu ClientDataSet já tinha os TFields pré definidos? Se você está criando os TFields antes não precisaria, pois o método faz isso pra você.

  2. Responder Marcos Rodrigues says:

    Também estou com este problema alguém tem a solução?

  3. Responder Andreano Lanusse says:

    Oi Marcos,

    Vai na unit DBXDBReaders na procedure CopyValueTypeProperties, localize a linha onde está
    if ValueType.DataType = TDBXDataTypes.WideStringType then

    e mude para

    if ValueType.DataType in [TDBXDataTypes.WideStringType, TDBXDataTypes.AnsiStringType] then

    Isso irá resolver o problema de truncar.

  4. Responder Rodrigo says:

    Olá Andreano, estou com uma dúvida, é a seguinte:

    tenho a consulta “SELECT * FROM TABELA WHERE ID=:pID”

    como passar pelo dbexpress vários valores para a coluna ID?

    visto que se eu utilizar, ClientDataSet1.Params[0].AsInteger := 1 só poderei trazer o registro cujo valor da coluna ID é 1,

    Gostaria de trazer vários registros cujo valor da coluna ID seria 1,2,3,4,60,90,80,56

  5. Responder Carlos Gonzaga says:

    Andreano !
    Seguindo a dica q vc passou p/ o Marcos. Como eu posto as alterações p/ uam nova unit DBXDBReaders.dcu ja q faz parte da lib da VCL?

  6. Responder Carlos Gonzaga says:

    Felismente so temos a liçença do Delphi 2007! Estou avaliando o delphi 2010 p/ adota-lo, mas estou encontrando estes probleminhas.

  7. Responder Rodrigo Martim says:

    Boa tarde Andreano,

    Fiz o ajuste no arquivo DBXDBReaders.pas, incluindo o conteudo postado por você ao Marcos, porem continuo com o problema.

    1º Pergunta: Existe alguma forma de depurar esta Unit? Gostaria de entender o que está acontecendo.

    2º Pergunta: Há necessidade de alguma compilação apos alterar o DBXDBReaders.pas ou só salvar e compilar o projeto?

    Embarcadero® Delphi® XE Version 15.0.3953.35171

    Agradecido desde já pela sua ajuda,
    Atenciosamente,
    Rodrigo Martim.

  8. Responder Rodrigo Martim says:

    OBS: A solução partiu 100% do Sr Andreano. estou postando por que notei que ele não postou este complemento.

    Problema resolvido:

    Apenas para complementar e ajudar pessoas que venham a ter a mesma duvida.

    Tem que compilar o .pas e jogar a dcu gerada pelo mesmo na pasta lib\debug e lib\release dentro das pasta do delphi, apos isso a correção irá funcionar.

    Mais uma vez obrigado pela dica Andreano.
    Sucesso!

  9. Responder Carlos Gonzaga says:

    Resolvi o problema com os campos definidos em run-time.
    Veja a rotina que define 2 (dois) campos do tipo string de tamanho variado no ClientDataSet (cdsBusca) .
    Isso responde tbm a pergunta do Carvalho, pois internamente o padrão para campos string é 20
    procedure TfrmBusca.DoDefColumns;
    var f:TFieldDef ;
    begin
    cdsBusca.FieldDefs.Clear ;

    f.Name :=’NOME’;
    f.DataType :=ftString ;
    f.Size :=50 ;

    f.Name :=’EMAIL’;
    f.DataType :=ftString ;
    f.Size :=80 ;

    cdsBusca.CreateDataSet ;
    end;

  10. Responder Wendel Wagner says:

    if Assigned(Reader) then
    begin
    Try
    //Tentando com a Opção Normal, se der erro copiamos um a um
    TDBXDataSetReader.CopyReaderToClientDataSet(Reader, pCds);
    except
    while Reader.Next do
    begin

    pCDS.Append;

    //Preenchendo a tabela
    for I := 0 to Reader.ColumnCount – 1 do
    begin
    //Pega o nome do campo
    VCampo := Copy( Reader. Query.Fields[I].FieldName,1,32);

    for y := 0 to pCds.FieldCount – 1 do
    begin
    VNome_Campo := Copy(pCds.Fields[y].FieldName,1,32);

    if VNome_Campo = VCampo then
    pCds.Fields[y].Value := Query.Fields[I].Value;
    end;
    end;

    pCds.FieldByName(‘SEL_GRID’).Value := ‘N’;

    pCDS.Post;

    Query.Next;
    end;
    End;
    end;

    Com a opção CopytoCds qdo tem coluna Blob da erro de “!FEATURE NOT IMPLEMENTED”..Estou tentando copiar coluna por coluna..mas ainda nao deu certo..existe outra forma de fazer isso?

  11. Responder Claudio says:

    Andreano, Boa Tarde.

    Estou utilizando TDBXReader para navegadar dados do servidor para o cliente.
    O problemas é o seguinte:

    Tenho um metodo no Servidor chamdo GetListaDeClientes e no cliente executo o seguinte comando
    vReader := proxyCliente.GetListaDeClientes;

    Quando executo esse comando FreeAndNil(vReader) e FreeAndNil(proxyCliente) o sistema da um erro ‘Invalid Pointer’, mas segui exatamento o exemplo que foi postado.
    O que pode ser?
    Estou utilizando Delphi2010.

  12. Responder Rafael Pasa says:

    Boa tarde Andreano!!!

    Preciso copiar um DBXreader para um objeto. Tenho uma classe que converte um clientDataSet para um objeto, segue o código abaixo:

    class procedure TMsysClassUtils.CarregarDoClientDataSet(const _AFields: TFields; _AObj: TObject);
    var
    PropList: PPropList;
    PropListCount: byte;
    I: integer;
    begin
    PropListCount := GetPropList(_AObj, PropList);
    for I := 0 to pred(PropListCount) do
    begin
    if not _AFields.FieldByName(string(PropList[I].Name)).IsNull then
    SetPropValue(_AObj, string(PropList[I].Name), _AFields.FieldByName(string(PropList[I].Name)).AsVariant);
    end;
    end;

    Então pensei em converter o DBXREader para um ClienteDataSet e depois para o objeto. mas ae tive um problema, no Reader vem um campo Observações(Tipo Blob).E a função CopyReaderToClientDataSet dispara um exceção NotImplemeted.
    Tem aguma forma de adaptar essa minha função para manipular um DBXREaders e suportar Blob, ou alguma outra solução para meu problema

  13. Responder Andreano Lanusse says:

    @Wender, o suporte a Blob foi implementado no Delphi XE2 Update 2, leia esse artigo http://www.andreanolanusse.com/pt/copyreadertoclientdataset-blob-e-a-mensagem-feature-not-implemented/

  14. Responder Júlio César Ferreira (@jcmferreira) says:

    Grande Andreano…

    Estou tentando adaptar o sistema da empresa para a tecnologia DataSnap, que é extremamente incrível.

    Em nosso caso, nossas queries no lado do servidor, são realizadas através dos componentes ADODB.

    Minha pergunta: É possível realizar um TDBXDataSetReader.Create a partir de um TADOQuery e disponibilizar o TDBXReader criado para as aplicações clientes?

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>