|
ActiveDelphi .: O site do programador Delphi! :.
|
Exibir mensagem anterior :: Exibir próxima mensagem |
Autor |
Mensagem |
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Jan 13, 2012 11:33 am Assunto: DBXReader de um TClientDataSet? [RESOLVIDO] |
|
|
Bom dia pessoal!
Existe algum macete na utilização do TDBXDataSetReader.Create( TDataSet, False )?
Estou criando um TClientDataSet temporario, com o método CreateDataSet, e preenchendo seu conteúdo de forma padrão. Até então, tudo ok!
Porém, gostaria que meu ServerMethod retornasse um TDBXReader desse dataset criado. Nesse momento, executo o comando acima mas o retorno é sempre nil, como se ele não criasse nada!
Imaginando que meu dataset criado se chama CDSEmpresas e que o mesmo possui 4 registros, o código da função é o abaixo:
Código: | result := TDBXDataSetReader.Create( CDSEmpresas, True ); |
Editado pela última vez por JCMF em Seg Jan 16, 2012 9:31 am, num total de 1 vez |
|
Voltar ao Topo |
|
|
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Jan 13, 2012 2:00 pm Assunto: |
|
|
E então pessoas? Ninguém já chegou a utilizar um DBXReader ou o TDBXDataSetReader? |
|
Voltar ao Topo |
|
|
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
|
Voltar ao Topo |
|
|
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Jan 13, 2012 3:23 pm Assunto: |
|
|
Decidi postar o código completo para dar uma ajuda... algumas classes e métodos são específicos de nosso sistema daqui então, não se preocupem com oq eles fazem... Mas, se for preciso, só perguntar!
O código tá grande mas super simples de entender!
Este é o código na minha aplicação servidor:
Código: | function TServerModuleEmpresa.GetUserCompanies(idUsuario: Integer; isMaster, isAdmin: Boolean): TDBXReader;
{ ** Procedimento interno do método para definir o ClientDataSet temporário para retorno ** }
function CreateCDSEmpresas: TClientDataSet;
var
cdsFieldPos: Integer;
cdsTable: TNewTable;
begin
{ ** Criando o objeto de retorno ** }
result := TClientDataSet.Create( Self );
{ ** Recuperando o objeto NewTable de empresas ** }
cdsTable := Structure.GetTable( 'empresas' );
{ ** Varrendo a estrutura da empresa para a definição dos campos do dataset de retorno ** }
for cdsFieldPos := 0 to High( cdsTable.Fields ) do
with cdsTable.Fields[cdsFieldPos] do
begin
case FieldType of
nftInteger, nftAutoIncrement:
result.FieldDefs.Add( Name, ftInteger, FieldSize );
nftVarchar, nftChar:
result.FieldDefs.Add( Name, ftString, FieldSize );
nftBlob:
result.FieldDefs.Add( Name, ftBlob, FieldSize );
nftDecimal:
result.FieldDefs.Add( Name, ftCurrency, FieldSize );
nftFloat:
result.FieldDefs.Add( Name, ftFloat, FieldSize );
nftDate:
result.FieldDefs.Add( Name, ftDate, FieldSize );
nftTime:
result.FieldDefs.Add( Name, ftTime, FieldSize );
nftDateTime:
result.FieldDefs.Add( Name, ftDateTime, FieldSize );
nftTimestamp:
result.FieldDefs.Add( Name, ftTimeStamp, FieldSize );
nftText:
result.FieldDefs.Add( Name, ftMemo, FieldSize );
end;
end;
{ ** Gerando o Dataset do objeto de retorno ** }
result.CreateDataSet;
end;
var
builder: TQueryBuilderAbstract;
builderIn: TQueryBuilderAbstract;
CDSEmpresas: TClientDataSet;
pos: Integer;
begin
{ ** Criando o dataset de retorno ** }
CDSEmpresas := CreateCDSEmpresas;
{ ** Definindo a consulta padrão para a seleção das empresas permitidas pelo usuário logado ** }
builder := GetPreparedBuilder;
try
{ ** Montando a instrução para filtrar as empresas permitidas para o usuário logado, quando não for MASTER ** }
if not isMaster and not isAdmin then
begin
{ ** Usuário não é Administrador do sistema ** }
builderIn := CreateQueryBuilder( 'empresas_usuarios', 'empresas_usuarios' );
builderIn.AddField( 'id_empresa' );
builderIn.AddWhere( 'id_usuario = ' + IntToStr( idUsuario ) );
builderIn.AddOrderBy( 'razao_social' );
builder.AddWhere( 'bloqueado = ' + QuotedStr( 'F' ) );
builder.AddWhere( 'and id in( ' + builderIn.GetInstruction + ' )' );
{ ** Liberando o objeto builderIn da memória ** }
builderIn.Destroy;
end;
{ ** Recuperando as empresas permitidas pelo usuário logado ** }
builder.Open;
{ ** Populando o objeto de retorno ** }
while not builder.Dataset.Eof do
begin
CDSEmpresas.Append;
{ ** Adicionando os campos para o registro ** }
for pos := 0 to builder.Dataset.FieldCount - 1 do
if CDSEmpresas.FindField( builder.Dataset.Fields[pos].FieldName ) <> nil then
CDSEmpresas.FieldByName( builder.Dataset.Fields[pos].FieldName ).Value := builder.Dataset.Fields[pos].Value;
{ ** Gravando a informação do registro no dataset de retorno ** }
CDSEmpresas.Post;
{ ** Avançando para o próximo registro disponível ** }
builder.Dataset.Next;
end;
{ ** Definindo o retorno do método ** }
result := TDBXDataSetReader.Create( CDSEmpresas, False );
{ ** Finalizando o objeto de retorno criado ** }
CDSEmpresas.Free;
{ ** Finalizando o objeto builder criado ** }
builder.Destroy( True );
except
raise Exception.Create( cstMsgSistemaFalhaEmpresasUsuarioLogado );
end;
end; |
Esta é a chamada na minha aplicação cliente:
Código: | function TFormSelecaoEmpresa.SelectionCompanies: Boolean;
var
DBXCommand: TDBXCommand;
DBXLeitor: TDBXReader;
begin
result := False;
{ ** Definindo o comando para a execução do Server Method ** }
DBXCommand := DataSnapConnection.DBXConnection.CreateCommand;
DBXCommand.CommandType := TDBXCommandTypes.DSServerMethod;
try
{ ** Recuperando as empresas disponíveis para o usuário logado no sistema ** }
DBXCommand.Text := 'TServerModuleEmpresa.GetUserCompanies';
DBXCommand.Prepare;
DBXCommand.Parameters[0].Value.SetInt32( usuario.Id );
DBXCommand.Parameters[1].Value.SetBoolean( usuario.Master );
DBXCommand.Parameters[2].Value.SetBoolean( usuario.Administrador );
try
DBXCommand.ExecuteUpdate;
{ ** Recuperando o retorno do comando realizado ** }
DBXLeitor := DBXCommand.Parameters[3].Value.GetDBXReader( True );
TDBXDataSetReader.CopyReaderToClientDataSet( DBXLeitor, cdsSelecao );
cdsSelecao.Active := True;
except on Error: Exception do
TCommonUtilities.MsgWarning( Error.Message );
end;
finally
FreeAndNil( DBXCommand );
end;
end; |
|
|
Voltar ao Topo |
|
|
andreano Novato
Registrado: Terça-Feira, 7 de Junho de 2005 Mensagens: 86
|
Enviada: Sex Jan 13, 2012 3:32 pm Assunto: |
|
|
Remove o try.. except
raise Exception.Create( cstMsgSistemaFalhaEmpresasUsuarioLogado );
end;
Tem algum erro acontecendo e você não pega por causa disso. |
|
Voltar ao Topo |
|
|
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Jan 13, 2012 3:36 pm Assunto: |
|
|
Apenas para testes, reduzi toda a implementação do método para oq está abaixo. Mas continua dando o mesmo problema:
Código: | function TServerModuleEmpresa.GetUserCompanies(idUsuario: Integer; isMaster, isAdmin: Boolean): TDBXReader;
begin
CDSEmpresas := CreateCDSEmpresas;
// CDSEmpresas é um TClientDataSet com 4 registros...
result := TDBXDataSetReader.Create( CDSEmpresas, False );
end; |
result sempre retorna (nil,nil)
Ao que parece, o TDBXDataSetReader.Create não está funcionando e pode ser por duas coisas: Ou não funciona com um TClientDataSet ou está bugado para o XE =\ |
|
Voltar ao Topo |
|
|
andreano Novato
Registrado: Terça-Feira, 7 de Junho de 2005 Mensagens: 86
|
Enviada: Sex Jan 13, 2012 4:49 pm Assunto: |
|
|
Se o DataSet tiver Blog não irá funcionar, o suporte a blog foi implementado no XE2 |
|
Voltar ao Topo |
|
|
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Jan 13, 2012 4:50 pm Assunto: |
|
|
andreano escreveu: | Se o DataSet tiver Blog não irá funcionar, o suporte a blog foi implementado no XE2 |
Não... não possui campos Blob. Apenas o padrão! |
|
Voltar ao Topo |
|
|
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sex Jan 13, 2012 4:53 pm Assunto: |
|
|
Também realizei o teste colocando apenas 3 campos do ClientDataSet e mesmo assim, não funciona!
Código: | CDSEmpresas := TClientDataSet.Create( Self );
CDSEmpresas.FieldDefs.Add( 'id', ftInteger );
CDSEmpresas.FieldDefs.Add( 'nome', ftString, 40 );
CDSEmpresas.FieldDefs.Add( 'bloqueado', ftBoolean );
CDSEmpresas.CreateDataSet;
CDSEmpresas.Append;
CDSEmpresas.Fields[0].AsInteger := 1;
CDSEmpresas.Fields[1].AsString := 'Teste DBXReader';
CDSEmpresas.Fields[2].AsBoolean := False;
CDSEmpresas.Post;
result := TDBXDataSetReader.Create( CDSEmpresas, False ); |
result é sempre (nil,nil)
PS.: Se vale de alguma coisa, o método acima está dentro de um TDSServerModule |
|
Voltar ao Topo |
|
|
marcosalles Moderador
Registrado: Quarta-Feira, 26 de Março de 2008 Mensagens: 1695 Localização: Muriaé Mg
|
Enviada: Sáb Jan 14, 2012 11:11 am Assunto: |
|
|
li este post desde de ontem é não é trivial resolver um problema a distancia
Mas teria jeito de ao invés de se utilizar um function com o retorno sendo
um clientDataSet , utilizar ao invés disso uma procedure cujo parâmetro
seje este ClientDataSet ... _________________ http://marcosalles.wordpress.com
Desenvolvo FreeLancer e presto Consultoria
Orientação Online DataSnap DbX ClientDataSet
POO , Padrões de Projeto e dúvidas de Delphi em
Geral |
|
Voltar ao Topo |
|
|
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sáb Jan 14, 2012 3:56 pm Assunto: |
|
|
marcosalles escreveu: | li este post desde de ontem é não é trivial resolver um problema a distancia
Mas teria jeito de ao invés de se utilizar um function com o retorno sendo
um clientDataSet , utilizar ao invés disso uma procedure cujo parâmetro
seje este ClientDataSet ... |
Até teria sim! O problema é que o retorno não é um ClientDataSet e sim um DBXReader.
Na verdade, oq realmente preciso é de um ClientDataSet temporário na aplicação cliente. Apenas para consulta de alguns pouquíssimos dados pelo usuário, sem nenhum tipo de edição.
O melhor jeito que encontrei foi o recurso de DBXReaders mas, não funciona! E se até o Andreano aparentemente não sabe explicar o motivo, estou começando a ficar desestimulado com o DBXReader =(( |
|
Voltar ao Topo |
|
|
marcosalles Moderador
Registrado: Quarta-Feira, 26 de Março de 2008 Mensagens: 1695 Localização: Muriaé Mg
|
|
Voltar ao Topo |
|
|
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sáb Jan 14, 2012 4:10 pm Assunto: |
|
|
Estou dando uma olhada nesse momento! Dando certo, aviso aqui! |
|
Voltar ao Topo |
|
|
JCMF Profissional
Registrado: Quarta-Feira, 28 de Abril de 2010 Mensagens: 578 Localização: Recife, PE
|
Enviada: Sáb Jan 14, 2012 4:14 pm Assunto: |
|
|
Solução muito interessante marcosalles!
A única diferença é que no meu caso, o cliente não define nenhum tipo de instrução SQL.
Oq realmente queria era algo a partir do código "Leitor:=Fcommand.ExecuteQuery;"... Ou seja, o meu cliente executa o método e recupera o "leitor", no formato DBXReader e depois é executado o CopyReaderToClientDataSet de forma super parecida com a sua implementação.
Existe uma forma de se fazer isso mas, utilizando o Fcommand.ExecuteUpdate e recuperando o DBXReader via Value.GetDBXReader?
Algo desse jeito:
Código: | DBXCommand := DataSnapConnection.DBXConnection.CreateCommand;
DBXCommand.CommandType := TDBXCommandTypes.DSServerMethod;
DBXCommand.Text := 'TServerModuleEmpresa.GetUserCompanies';
DBXCommand.Prepare;
DBXCommand.Parameters[0].Value.SetInt32( usuario.Id );
DBXCommand.Parameters[1].Value.SetBoolean( usuario.Master );
DBXCommand.Parameters[2].Value.SetBoolean( usuario.Administrador );
DBXCommand.ExecuteUpdate;
DBXLeitor := DBXCommand.Parameters[3].Value.GetDBXReader( True );
TDBXDataSetReader.CopyReaderToClientDataSet( DBXLeitor, cdsSelecao ); |
Não sei se estou conseguindo me fazer entender mas... dentro do método TServerModuleEmpresa.GetUserCompanies, o DBXReader é criado e retornado. |
|
Voltar ao Topo |
|
|
marcosalles Moderador
Registrado: Quarta-Feira, 26 de Março de 2008 Mensagens: 1695 Localização: Muriaé Mg
|
Enviada: Sáb Jan 14, 2012 10:48 pm Assunto: |
|
|
Para piorar , comigo eu não tive nenhum problema .
Consegui conexão e popular o cdsSelecao na aplicação cliente
Claro utilizando sua simplificação
Citação: | CDSEmpresas := TClientDataSet.Create( Self );
CDSEmpresas.FieldDefs.Add( 'id', ftInteger );
CDSEmpresas.FieldDefs.Add( 'nome', ftString, 40 );
CDSEmpresas.FieldDefs.Add( 'bloqueado', ftBoolean );
CDSEmpresas.CreateDataSet;
CDSEmpresas.Append;
CDSEmpresas.Fields[0].AsInteger := 1;
CDSEmpresas.Fields[1].AsString := 'Teste DBXReader';
CDSEmpresas.Fields[2].AsBoolean := False;
CDSEmpresas.Post;
result := TDBXDataSetReader.Create( CDSEmpresas, False );
|
Citação: | procedure TForm8.Button1Click(Sender: TObject);
var
DBXReader:TDBXReader;
DBXCommand:TDBXCommand;
DBXLeitor:TdbxReader;
begin
DBXCommand := DataSnap_Ajuda_JCMF.DBXConnection.CreateCommand;
DBXCommand.CommandType := TDBXCommandTypes.DSServerMethod;
DBXCommand.Text := 'TServerMethods1.GetUserCompanies';
DBXCommand.Prepare;
DBXCommand.Parameters[0].Value.SetInt32(1 );
DBXCommand.Parameters[1].Value.SetBoolean(true );
DBXCommand.Parameters[2].Value.SetBoolean(true );
DBXCommand.ExecuteUpdate;
DBXLeitor := DBXCommand.Parameters[3].Value.GetDBXReader( True );
TDBXDataSetReader.CopyReaderToClientDataSet( DBXLeitor, cdsSelecao );
end; |
_________________ http://marcosalles.wordpress.com
Desenvolvo FreeLancer e presto Consultoria
Orientação Online DataSnap DbX ClientDataSet
POO , Padrões de Projeto e dúvidas de Delphi em
Geral |
|
Voltar ao Topo |
|
|
|
|
Enviar Mensagens Novas: Proibido. Responder Tópicos Proibido Editar Mensagens: Proibido. Excluir Mensagens: Proibido. Votar em Enquetes: Proibido.
|
|