DBXReader para ClientDataSet e alterar
Olá pessoal, estou tentando fazer uma aplicação aqui que se tudo der certo irá se comunicar tanto com uma aplicação cliente desktop como com um app para Android. Para isso estou desenvolvendo minhas classes de manipulação de dados no servidor usando DBXReader. Portanto criei uma classe onde tenho o método alterar que recebe como parametro um DBXReader que conterá o registro que foi alterado pelo cliente.
O problema é que quando jogo esse DBXreader para um CDS e realizo um applyUpdates, ao invez de executar um Update ele tenta realizar um insert o que ocasiona um erro de PK pois ela ja existe no banco.
Segue meu codigo para que possam entender melhor:
Alguem saberia me dizer se tem alguma maneira de forçar o CDS a realizar um update ao invez de um insert?
O problema é que quando jogo esse DBXreader para um CDS e realizo um applyUpdates, ao invez de executar um Update ele tenta realizar um insert o que ocasiona um erro de PK pois ela ja existe no banco.
Segue meu codigo para que possam entender melhor:
procedure TDaoServerClass.pprAlterar(ipObj: TDBXReader);
begin
TDBXClientDataSetReader.CopyReaderToClientDataSet(ipObj, FCds);
FCds.Edit;
FCds.Post;
FCds.ApplyUpdates(0);
end;
//FCds é um CDS que esta no meu DataModule o qual já esta corretamente ligado a um Provider->TSQLDataSet->TSQLConncetion.
Alguem saberia me dizer se tem alguma maneira de forçar o CDS a realizar um update ao invez de um insert?
Rafael Costa
Curtidas 0
Respostas
Claudia Nogueira
25/11/2012
Sabe o que pode ser também, o FCds não estar posicionado no registro que você está alterando, aí por exemplo você está tentando alterar um que a chave primária = 2, hora que você chama pra editar o FCds se posiciona em outro registro, provavelmente o primeiro, aí como você está mandando o código 2 e ele está posicionado no 1 e não no 2 aí dá o erro da FK porque ele está tentando mudar o código do 1 pra 2 e o 2 já existe.
Com esse erro da FK está dando a impressão que está inserindo, mas na verdade está editando mesmo.
Quer ver, faz um teste aí, hora de chamar a função pra alterar não passa o field do código. Aí provavelmente não vai dar o erro, mas vai editar outro registro.
Com esse erro da FK está dando a impressão que está inserindo, mas na verdade está editando mesmo.
Quer ver, faz um teste aí, hora de chamar a função pra alterar não passa o field do código. Aí provavelmente não vai dar o erro, mas vai editar outro registro.
GOSTEI 0
Rafael Costa
25/11/2012
Olá Claudiadnh, primeiramente obrigado por responder, mas este não é o caso pois eu garanto que esse DBXReader só possui um registro quando eu chamo a função no meu cliente. E também para ter certeza eu já verifiquei o recordcount dele e é sempre um.
E a operação que esta sendo realizada é um insert mesmo pois eu coloquei um breakpoint no metodo BeforeUpdateRecord do meu provider e o parametro UpdateKind esta setado para ukInsert.
E a operação que esta sendo realizada é um insert mesmo pois eu coloquei um breakpoint no metodo BeforeUpdateRecord do meu provider e o parametro UpdateKind esta setado para ukInsert.
GOSTEI 0
Claudia Nogueira
25/11/2012
Hum entendi, então realmente não é o que eu pensava.
Vou tentar ver mais alguma coisa aqui, enquanto isso vamos ver se mais alguém responde.
Vou tentar ver mais alguma coisa aqui, enquanto isso vamos ver se mais alguém responde.
GOSTEI 0
Rodolpho Silva
25/11/2012
Colega Rafael,
Esta função:
Está fazendo uma cópia dos dados do DBXReader ao Cds logo, isso é via "insert". Dessa maneira,
este registro fica marcado no Delta do Cds como "novo" então, no momento do ApplyUpdate o DataProvider
realizará um insert na base de dados. E mesmo que você faça isso:
Não invalida a definição de "insert" do registro para o DataProvider. Pelo que entendi, você só conseguirá resolver o problema de 2 maneiras:
1) Abrir o seu "FCds" com o registro em questão e atualizar conforme sua regra de negócios
2) Passar um Cds como parâmetro (e não mais DBXReader) onde este contém os dados à serem atualizados. Para fazer a cópia do seu Cds de
parâmetro ao FCds, basta fazer isso:
Pois são copiados todos os registros e seus respectivos estados (update, delete, etc...)
Bem, espero ter ajudado.
Esta função:
TDBXClientDataSetReader.CopyReaderToClientDataSet(ipObj, FCds);
Está fazendo uma cópia dos dados do DBXReader ao Cds logo, isso é via "insert". Dessa maneira,
este registro fica marcado no Delta do Cds como "novo" então, no momento do ApplyUpdate o DataProvider
realizará um insert na base de dados. E mesmo que você faça isso:
FCds.Edit; FCds.Post; FCds.ApplyUpdates(0);
Não invalida a definição de "insert" do registro para o DataProvider. Pelo que entendi, você só conseguirá resolver o problema de 2 maneiras:
1) Abrir o seu "FCds" com o registro em questão e atualizar conforme sua regra de negócios
2) Passar um Cds como parâmetro (e não mais DBXReader) onde este contém os dados à serem atualizados. Para fazer a cópia do seu Cds de
parâmetro ao FCds, basta fazer isso:
FCds.Data := CdsParametro.Data;
Pois são copiados todos os registros e seus respectivos estados (update, delete, etc...)
Bem, espero ter ajudado.
GOSTEI 0
Marco Salles
25/11/2012
Do modo que vc esta fazendo , vc esta carregando o cds com o CopyReaderToClientDataSet e isto não passa pelo provider
Neste momento vc esta carregando o Cds com os dados
quando vc instrue o cds em memória para editar ele ira editar
quando vc instrue o Cds para salvar ele ira salva
Porém quando vc instrue o Cds para dar um applayUpdates o provider ira resolver
ele tentara aplicar todos os dados que estão em memória
Vc pode ver isto atraves do Xml gerado pelo Open Close ou CopyReaderToClientDataSet ... Os dois Xml indicam o que
alteração , edição ou exclusão.. Esses Xml que é trafegado e resolvido pelo provider
Tb vc pode utilizar o ChangeCount para ver esta alteração
compare
Neste momento vc esta carregando o Cds com os dados
quando vc instrue o cds em memória para editar ele ira editar
quando vc instrue o Cds para salvar ele ira salva
Porém quando vc instrue o Cds para dar um applayUpdates o provider ira resolver
ele tentara aplicar todos os dados que estão em memória
Vc pode ver isto atraves do Xml gerado pelo Open Close ou CopyReaderToClientDataSet ... Os dois Xml indicam o que
alteração , edição ou exclusão.. Esses Xml que é trafegado e resolvido pelo provider
Tb vc pode utilizar o ChangeCount para ver esta alteração
compare
procedure TDaoServerClass.pprAlterar(ipObj: TDBXReader); begin TDBXClientDataSetReader.CopyReaderToClientDataSet(ipObj, FCds); Showmessage(inttostr(Fcds.ChangeCount)); //Vc espera que vc Zero mas não é //FCds.Edit; //FCds.Post; //FCds.ApplyUpdates(0); end;
procedure TDaoServerClass.pprAlterar(ipObj: TDBXReader); begin Fcds.close; Fcds.open; Showmessage(inttostr(Fcds.ChangeCount)); //Vc espera que vc Zero e È ... //FCds.Edit; //FCds.Post; //FCds.ApplyUpdates(0); end;
GOSTEI 0
Rafael Costa
25/11/2012
Então, a opção de passar um ClientDataSet não é viável, pois irei precisar chamar essa função de um app do Android e até onde eu já vi nas classes exportadas pelo Delphi para realizar a comunicação com o Android não existe o ClientDataSet.
Quanto a outra solução eu já tinha imaginado que poderia dar certo mas não queria utiliza-la, pois terei que novamente realizar uma busca no banco, tudo bem que agora será pelo Id da tabela e o meu server esta na mesma maquina do banco, mas ainda sim será uma outra busca.
mas se não tiver outra solução vai ser essa mesmo.
Obrigado a todos pela ajuda.
Quanto a outra solução eu já tinha imaginado que poderia dar certo mas não queria utiliza-la, pois terei que novamente realizar uma busca no banco, tudo bem que agora será pelo Id da tabela e o meu server esta na mesma maquina do banco, mas ainda sim será uma outra busca.
mas se não tiver outra solução vai ser essa mesmo.
Obrigado a todos pela ajuda.
GOSTEI 0
Rodolpho Silva
25/11/2012
Então, a opção de passar um ClientDataSet não é viável, pois irei precisar chamar essa função de um app do Android e até onde eu já vi nas classes exportadas pelo Delphi para realizar a comunicação com o Android não existe o ClientDataSet.
Quanto a outra solução eu já tinha imaginado que poderia dar certo mas não queria utiliza-la, pois terei que novamente realizar uma busca no banco, tudo bem que agora será pelo Id da tabela e o meu server esta na mesma maquina do banco, mas ainda sim será uma outra busca.
mas se não tiver outra solução vai ser essa mesmo.
Obrigado a todos pela ajuda.
Quanto a outra solução eu já tinha imaginado que poderia dar certo mas não queria utiliza-la, pois terei que novamente realizar uma busca no banco, tudo bem que agora será pelo Id da tabela e o meu server esta na mesma maquina do banco, mas ainda sim será uma outra busca.
mas se não tiver outra solução vai ser essa mesmo.
Obrigado a todos pela ajuda.
Entendi. Por isso é importante o uso de uma framework ORM (desenvolvida por nós mesmo ou de terceiros) para lidarmos melhor com situações como estas.
Segue algumas frameworks ORM: [url]http://code.google.com/p/delphi-orm/[/url] e [url]http://tiopf.sourceforge.net/index.shtml[/url]
GOSTEI 0
Marco Salles
25/11/2012
se ue pudesse editar ... desculpe o instrue repetido tres vezes no post anterior . È que eu escrevo sem ler e muito rápido
Realmente o framework ORM muito interressante . Porém uma outra saida é zerar este log de alterações
basta chmar método MergeChangeLog apos vc carrega-lo veja
Perceba , eu não estou dizendo que esta é a melhor solução , so coloquei o pq do erro obtido por vc
Realmente o framework ORM muito interressante . Porém uma outra saida é zerar este log de alterações
basta chmar método MergeChangeLog apos vc carrega-lo veja
procedure TDaoServerClass.pprAlterar(ipObj: TDBXReader); begin TDBXClientDataSetReader.CopyReaderToClientDataSet(ipObj, FCds); Fcds.MergeChangeLog; //***************************************************** FCds.Edit; FCds.Post; FCds.ApplyUpdates(0); end; //FCds é um CDS que esta no meu DataModule o qual já esta corretamente ligado a um Provider->TSQLDataSet->TSQLConncetion.
Perceba , eu não estou dizendo que esta é a melhor solução , so coloquei o pq do erro obtido por vc
GOSTEI 0
Rafael Costa
25/11/2012
Realmente framework ORM é uma boa opção, eu uso bastante quando estou desenvolvendo em Java.
Mas quando estou no Delphi me sinto como se estivesse deixando de usufruir das vantagens dos componentes do Delphi (CDS, Provider... etc), pois teria que criar meus Models e atribuir campo a campo.
Ex.:
meuObj.nome := EditNome.text;
meuObj.idade := EditIdade.text
enquanto usando CDS eu apenas ligo os meus DBEdits e pronto. Por isso eu tentando fazer essa classe, pois minha ideia era continuar usando o CDS no cliente porem no momento de gravar ao invez de utilizar o applyUpdate direto do CDS, eu o transformaria em um DBXReader e o passaria para minha classe no server que faria o processo inverso e então realizaria a gravação no banco, não necessitando assim a escrita de comandos SQL para insert, update ou delete.
Vou tentar a solução proposta pelo Marco, se der certo post o resultado aqui.
Valeu..
Mas quando estou no Delphi me sinto como se estivesse deixando de usufruir das vantagens dos componentes do Delphi (CDS, Provider... etc), pois teria que criar meus Models e atribuir campo a campo.
Ex.:
meuObj.nome := EditNome.text;
meuObj.idade := EditIdade.text
enquanto usando CDS eu apenas ligo os meus DBEdits e pronto. Por isso eu tentando fazer essa classe, pois minha ideia era continuar usando o CDS no cliente porem no momento de gravar ao invez de utilizar o applyUpdate direto do CDS, eu o transformaria em um DBXReader e o passaria para minha classe no server que faria o processo inverso e então realizaria a gravação no banco, não necessitando assim a escrita de comandos SQL para insert, update ou delete.
Vou tentar a solução proposta pelo Marco, se der certo post o resultado aqui.
Valeu..
GOSTEI 0
Rafael Costa
25/11/2012
E complementando, usando o DBXReader eu ainda conseguiria me comunicar com o meu server através de um app Android, IOS, etc.
GOSTEI 0
Rafael Costa
25/11/2012
É isso ai pessoal consegui fazer usando o Fcds.MergeChangeCount, apesar que tiver que fazer um código um tanto dúvidoso.. rsrs, mas enfim, ainda acho melhor do que fazer a busca novamente no banco.
Segue o código para caso alguem precise:
Valeu pessoal. Problema resolvido.
Segue o código para caso alguem precise:
procedure TDaoServerClass.pprAlterar(ipObj: TDBXReader);
var
vaCds: TClientDataSet;
I: Integer;
begin
vaCds := TClientDataSet.Create(nil);
try
TDBXClientDataSetReader.CopyReaderToClientDataSet(ipObj, FCds);
vaCds.Data := FCds.Data;
// vou alterar todos os registros agora. Tenho que fazer isso pois senao na hora de fazer o applyUpdates nada ira ocorrer
for I := 0 to FCds.FieldCount - 1 do
begin
if not (pfInKey in (FCds.Fields[i].ProviderFlags)) then
begin
FCds.Edit;
FCds.Fields[I].Clear;
FCds.Post;
end;
end;
// zerando o ChangeCount do CDS
FCds.MergeChangeLog;
// voltando os valores originais. Fazendo isso, faço o CDS achar que seus valores foram alterados, realizando um update ao inves do insert no momento do apply.
for I := 0 to FCds.FieldCount - 1 do
begin
FCds.Edit;
FCds.Fields[I] := vaCds.Fields[I];
FCds.Post;
end;
// gravando no banco
FCds.ApplyUpdates(0);
finally
vaCds.Free;
end;
Valeu pessoal. Problema resolvido.
GOSTEI 0
Marco Salles
25/11/2012
Bem Rafael , desculpe mas vc parece não ter entendido o Objetivo do método MergeChangelong
Tb não da para entender o pq que vc Aplica no banco algo que vc ja tem
È so carregar com o
TDBXClientDataSetReader.CopyReaderToClientDataSet(ipObj, FCds);
da um Fcds.MergeChangelong e toda alteração que vc fizer posteriore será considerada um Updade e não Um Insert
Desculpe mas esta muito estranho tudo isto
[]sds
Tb não da para entender o pq que vc Aplica no banco algo que vc ja tem
È so carregar com o
TDBXClientDataSetReader.CopyReaderToClientDataSet(ipObj, FCds);
da um Fcds.MergeChangelong e toda alteração que vc fizer posteriore será considerada um Updade e não Um Insert
Desculpe mas esta muito estranho tudo isto
[]sds
GOSTEI 0
Rafael Costa
25/11/2012
Olá Marco, acho que você não entendeu qual a ideia da minha procedure.
é o seguinte, esse DBXReader que é passado como parametro já esta com as informações alteradas, o que eu preciso é gravar elas no banco. Se eu faço um mergeChangeLog e logo apos faço um applyUpdates, nada será gravado no banco, pois para o CDS nada foi alterado.
Por isso faço essa volta ai. Salvo os valores originais em outro CDS, depois limpo todos os campos do Fcds e então faço o MergeChangeLog. E então, percorro ele novamente e volto os valores originais e faço o applyUpdates que agora sim irá gerar os sqls para Update e não Insert.
Pode ser que tenha outra forma mais simples de fazer isso, mas não consegui encontrá-la.
Flw
é o seguinte, esse DBXReader que é passado como parametro já esta com as informações alteradas, o que eu preciso é gravar elas no banco. Se eu faço um mergeChangeLog e logo apos faço um applyUpdates, nada será gravado no banco, pois para o CDS nada foi alterado.
Por isso faço essa volta ai. Salvo os valores originais em outro CDS, depois limpo todos os campos do Fcds e então faço o MergeChangeLog. E então, percorro ele novamente e volto os valores originais e faço o applyUpdates que agora sim irá gerar os sqls para Update e não Insert.
Pode ser que tenha outra forma mais simples de fazer isso, mas não consegui encontrá-la.
Flw
GOSTEI 0
Marco Salles
25/11/2012
Quem faz alteração é o ExecuteUpdate e não ha retorno de DbXreader
Utilizar o ExecuteQuery retorna DbXreader , porem em Edit o retorno é Nil
qual a isntrução que vc esta utilizando para fazer esta alteração
Normalamente é assim
Postei algo que eu utilizo para Editar dados com TDBXCommand , vc esta utilizando algo parecido ?
Ou vc esta editando e retornando com o select Campso From Tabela o ReaderDbx ???
desculpe mas queria entender , apesar de lhe aconselhar o MergeChangeLong ainda esta obscuro o que vc esta fazendo
[]sds
Utilizar o ExecuteQuery retorna DbXreader , porem em Edit o retorno é Nil
qual a isntrução que vc esta utilizando para fazer esta alteração
Normalamente é assim
var
FConnetion:TDBXConnection;
cmd: TDBXCommand;
begin
Fconnetion:=TDBXConnectionFactory.GetConnectionFactory.GetConnection
('COnexaoValida','SYSDBA','masterkey');
try
cmd:=Fconnetion.CreateCommand;
try
cmd.Text := 'UPDATE '+Table+ ' SET '+Fields+'='+QuotedStr('Alterar')+' Where Country = '+QuotedStr('Condicao');
Result := cmd.ExecuteQuery; //Retorno é Nil eu utilizo o cmd.ExecuteUpdate para comandos de Atualização
except
raise;
end;
finally
Fconnetion.free;
end;
end;
Postei algo que eu utilizo para Editar dados com TDBXCommand , vc esta utilizando algo parecido ?
Ou vc esta editando e retornando com o select Campso From Tabela o ReaderDbx ???
desculpe mas queria entender , apesar de lhe aconselhar o MergeChangeLong ainda esta obscuro o que vc esta fazendo
[]sds
GOSTEI 0
Rafael Costa
25/11/2012
Não entendi bem o que você quis dizer, mas não uso esse TDBXCommand em lugar algum (Na verdade uso, mas somente nas buscas e não em updates ou inserts). Quem efetua a gravação no banco é o CDS->Provider->TSQLDataset. Vou tentar explicar melhor como todo o processo funciona.
Estou desenvolvendo uma aplicação multicamada, onde terei uma aplicação server, uma aplicação cliente Desktop e uma aplicação cliente Mobile(Android). No meu server tenho a classe TDaoServerClass que é uma classe abstrata para as minhas outras classes como por exemplo TDaoUsuarioServer. Essa TDaoServerClass irá conter algumas funções basicas que todas as classes que herdarem deram irão conter tbm as quais são: operações CRUD, sendo que a busca pode ser por ID ou todas.
No momento estou desenvolvendo somente a aplicação Server e Cliente desktop. então na minha aplicação cliente faço uma conexao datasnap normal (CDS->DSProviderConnection). Porém ao clicar no botão buscar por exemplo eu faço uma chamada a minha função no server. ex.:
e no momento de alterar/salvar/deletar faço algo semelhante. ex.:
Essa foi uma maneira que encontrei (ainda não sei se vai funcionar em 100% dos casos) de não precisar escrever SQLs para INSERT/UPDATE e DElete e também garantir que quando minha aplicação mobile estiver pronta ela somente irá precisar criar um DBXReader e chamar as funções do meu server.
É isso ai, espero ter explicado melhor desta vez.
flw.
Estou desenvolvendo uma aplicação multicamada, onde terei uma aplicação server, uma aplicação cliente Desktop e uma aplicação cliente Mobile(Android). No meu server tenho a classe TDaoServerClass que é uma classe abstrata para as minhas outras classes como por exemplo TDaoUsuarioServer. Essa TDaoServerClass irá conter algumas funções basicas que todas as classes que herdarem deram irão conter tbm as quais são: operações CRUD, sendo que a busca pode ser por ID ou todas.
TDaoServerClass = class abstract(TPersistent)
strict private
procedure ppvCommit(ipCds: TClientDataSet);
strict protected
FNomeTabela: string;
FDataSet: TSQLDataSet;
FProvider: TDataSetProvider;
FCds: TClientDataSet;
FCommand: TDBXCommand;
function fprSalvar(ipObj: TDBXReader): Integer; virtual;
procedure pprAlterar(ipObj: TDBXReader); virtual;
procedure pprExcluir(ipId: Integer); virtual; abstract;
function fprBuscar(ipId: Integer): TDBXReader; virtual;
function fprBuscarTodos: TDBXReader; virtual;
...
//restante do codigo omitido
No momento estou desenvolvendo somente a aplicação Server e Cliente desktop. então na minha aplicação cliente faço uma conexao datasnap normal (CDS->DSProviderConnection). Porém ao clicar no botão buscar por exemplo eu faço uma chamada a minha função no server. ex.:
var
vaDao:TDaoUsuarioServerClient;
vaReader:TDBXReader;
begin
DataModule.ClientDataSetUsuario.open;//nao traz nada pq no server eu coloquei no SQL where codigo =0;
vaDao := TDaoUsuarioServerClient.Create(ClientModule1.SQLConnection1.DBXConnection);
vaReader := vaDao.fprBuscarTodos;
TDBXClientDataSetReader.CopyReaderToClientDataSet(vaReader, DataModule.ClientDataSetUsuario);//carrego o Cds
end;
e no momento de alterar/salvar/deletar faço algo semelhante. ex.:
procedure TForm1.btnAlterarClick(Sender: TObject);
var
vaUser: TDaoUsuarioServerClient;
vaReader: TDBXReader;
begin
try
DataModule.ClientDataSetUsuario.Post;
vaUser := TDaoUsuarioServerClient.Create(DataModule.SQLConnection1.DBXConnection);
vaReader := TDBXDataSetReader.Create(DataModule.ClientDataSetUsuario);
vaUser.pprAlterar(vaReader);
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
Essa foi uma maneira que encontrei (ainda não sei se vai funcionar em 100% dos casos) de não precisar escrever SQLs para INSERT/UPDATE e DElete e também garantir que quando minha aplicação mobile estiver pronta ela somente irá precisar criar um DBXReader e chamar as funções do meu server.
É isso ai, espero ter explicado melhor desta vez.
flw.
GOSTEI 0
Marco Salles
25/11/2012
Bem , coloquei o código acima que é uma das formas de carregar um TDBXReader . Um outro modo de carregar um TDBXReader é
utilizar um comando do tipo TDBXDataSetReader.Create(ClientDataSet, False (* InstanceOwner *) ).
Quando vc faz vaReader := vaDao.fprBuscarTodos vc esta carregando um TDBXReader ... A minha dúvida foi exatamente esta
como vc esta carregando este DbxRerader ???
utilizar um comando do tipo TDBXDataSetReader.Create(ClientDataSet, False (* InstanceOwner *) ).
Quando vc faz vaReader := vaDao.fprBuscarTodos vc esta carregando um TDBXReader ... A minha dúvida foi exatamente esta
como vc esta carregando este DbxRerader ???
GOSTEI 0
Rafael Costa
25/11/2012
Sim, fprBuscarTodos é uma função no meu server que me retorna um TDBXReader com todos os registros.
GOSTEI 0
Marco Salles
25/11/2012
Sim, fprBuscarTodos é uma função no meu server que me retorna um TDBXReader com todos os registros.
Sim , mas qual o código que que vc faz isto .. Eu li passei dois modos , por acaso vc esta utilizando um terceiro ?
somemte a instrução de carregar o DbxReader que eu estou comentando ... Pode passar ou é algo confidencial ?
[]sds
GOSTEI 0
Rafael Costa
25/11/2012
Descuple, não tinha entendido o que você estava querendo. Estou usando o Command, semelhante ao que você mostrou ai,
mas utilizo ele somente nos meus métodos de busca.
Segue o código das minhas duas function padrão de busca
mas utilizo ele somente nos meus métodos de busca.
Segue o código das minhas duas function padrão de busca
function TDaoServerClass.fprBuscar(ipId: Integer): TDBXReader; var vaSql: string; begin //FDataSet é um TSQLDataSet que se encontra no meu DataModule, nele eu já coloquei o meu SQL. ex. select * from usuario where codigo = 0; vaSql := TSQLGenerator.removeFilters(FDataSet.commandText);//retiro qualquer clausula where do sql vaSql := TSQLGenerator.filterInteger(FNomeTabela, coID, ipId, vaSql);//adiciono uma clausula where filtrando pelo ID FCommand.Text := vaSql; Result := FCommand.ExecuteQuery; end; function TDaoServerClass.fprBuscarTodos: TDBXReader; var vaSql: string; begin vaSql := TSQLGenerator.removeFilters(FDataSet.commandText); FCommand.Text := vaSql; Result := FCommand.ExecuteQuery; end;
GOSTEI 0