Pesquisa com clientedataset e SQL
Ola caro programadores,
Estou migrando todo o meu sistema do Paradox para o FireBird. Estou com uma divida na eleboração das pesquisas (Consulta). Tenho um cadastro de cliente, onde no mesmo tem um botão consultar, antes no paradox usa o findkey e o findnearest, agora no FireBird comecei a usar o locate mas pesquisando verifiquei que esta não é a melhor opção, tabém não consigo usar as vantagem da pesquisa em sql de busca o conteúdo no começo no fim e no meio.
Uso os componetes:
SQLconection, SQLDataset, datasetprovider, Clientdataset, datasource.
No SQLdataset já tem uma SQL filtrando a tabela e checando qual empresa esta ativada: select * from cliente where LOJA = :Empresa
este parametro e passado na hora da abertura, até ai tudo bem funciona beleza.
o Problema e o seguinda quero consultar um cliente por código, nome ou CPF/CNPJ. quando passo esta SQL(select * from CLIENTE where LOJA = :Empresa and NOME = :nome) para o SQLDATASET e mando abrir o CDS da um erro de login ou password, estranho pois a senha e o login estão corretos.
Fiz de uma forma diferente como fazia no Paradox que erá realizar a pesquisa com o QUERY achar o registro desejado e depois pesquisa com o findkey direto deu certo mas dai continuo usando o locate.
Como devo fazer para fazer uma pesquisa com SQL e Clientedataset ?
qual a forma correta ?
Um grande abraço a todos.
Hugo Fabrício
Estou migrando todo o meu sistema do Paradox para o FireBird. Estou com uma divida na eleboração das pesquisas (Consulta). Tenho um cadastro de cliente, onde no mesmo tem um botão consultar, antes no paradox usa o findkey e o findnearest, agora no FireBird comecei a usar o locate mas pesquisando verifiquei que esta não é a melhor opção, tabém não consigo usar as vantagem da pesquisa em sql de busca o conteúdo no começo no fim e no meio.
Uso os componetes:
SQLconection, SQLDataset, datasetprovider, Clientdataset, datasource.
No SQLdataset já tem uma SQL filtrando a tabela e checando qual empresa esta ativada: select * from cliente where LOJA = :Empresa
este parametro e passado na hora da abertura, até ai tudo bem funciona beleza.
o Problema e o seguinda quero consultar um cliente por código, nome ou CPF/CNPJ. quando passo esta SQL(select * from CLIENTE where LOJA = :Empresa and NOME = :nome) para o SQLDATASET e mando abrir o CDS da um erro de login ou password, estranho pois a senha e o login estão corretos.
Fiz de uma forma diferente como fazia no Paradox que erá realizar a pesquisa com o QUERY achar o registro desejado e depois pesquisa com o findkey direto deu certo mas dai continuo usando o locate.
Como devo fazer para fazer uma pesquisa com SQL e Clientedataset ?
qual a forma correta ?
Um grande abraço a todos.
Hugo Fabrício
Hugofab
Curtidas 0
Respostas
Vinicius2k
11/10/2004
Colega,
A forma que q vc está tentando implementar (alterar a CommandText do TSQLDataSet em run time ) é a forma correta. O que é estranho, ao menos para mim, é um erro de login nesta operação... qual é exatamente a mensagem ?
Este problema *pode* estar na TSQLConnection. Verifique se a propriedade [b:1fb479a82e]KeepConnection[/b:1fb479a82e] está setada para [b:1fb479a82e]True[/b:1fb479a82e]. Esta propriedade é responsável por manter a conexão com o servidor, mesmo que não exista nenhum DataSet aberto. Se ela estiver setada para False, a reabertura do TSQLDataSet estará exigindo que ela se conecte novamente ao servidor, exigindo a autenticação, que se for dinâmica, vc, provavelmente, passou na abertura da aplicação.
Sobre utilizar qualquer parte do campo basta que o operador da sua segunda condição no WHERE seja o LIKE e ao atribuir valores aos paramentros vc se utilize dos caracteres coringas ´[b:1fb479a82e]¬[/b:1fb479a82e]´, assim :
Vc tem razão sobre o uso do Locate. É uma escolha ruim em aplicações C/S.
Espero ter ajudado.
T+
A forma que q vc está tentando implementar (alterar a CommandText do TSQLDataSet em run time ) é a forma correta. O que é estranho, ao menos para mim, é um erro de login nesta operação... qual é exatamente a mensagem ?
Este problema *pode* estar na TSQLConnection. Verifique se a propriedade [b:1fb479a82e]KeepConnection[/b:1fb479a82e] está setada para [b:1fb479a82e]True[/b:1fb479a82e]. Esta propriedade é responsável por manter a conexão com o servidor, mesmo que não exista nenhum DataSet aberto. Se ela estiver setada para False, a reabertura do TSQLDataSet estará exigindo que ela se conecte novamente ao servidor, exigindo a autenticação, que se for dinâmica, vc, provavelmente, passou na abertura da aplicação.
Sobre utilizar qualquer parte do campo basta que o operador da sua segunda condição no WHERE seja o LIKE e ao atribuir valores aos paramentros vc se utilize dos caracteres coringas ´[b:1fb479a82e]¬[/b:1fb479a82e]´, assim :
with SQLDataSet1 do begin Close; CommandText:= ´select * from CLIENTE where (LOJA = :Empresa) and (NOME like :nome)´; ParamByName(´Empresa´).AsInteger:= 1; // por exemplo ParamByName(´nome´).AsString:= ´¬´ + Edit1.Text + ´¬´; // por exemplo end; ClientDataSet1.Close; ClientDataSet1.Open;
Vc tem razão sobre o uso do Locate. É uma escolha ruim em aplicações C/S.
Espero ter ajudado.
T+
GOSTEI 0
Hugofab
11/10/2004
Vinicius,
a mensagem é esta : DBexpress Error:Invalid Username/Password.
Verifiquei a opção que vc me falou e esta setada como True, o comando que estou mandando é este :
SQLDataSet.close;
clientedataset.close;
SQLDataSet.CommandText := ´select * from CLIENTE where LOJA = :Empresa and CODIGO = :codigo´;
SQLDataSet.Params.ParamByName(´Empresa´).AsString:= CDSparametro.fieldbyname(´Empresa´).AsString;
SQLDatatSet.Params.ParamByName(´codigo´).AsString:=´0´+edtnumero.Text;
SQLDataSet.open;
ClienteDataSet.Open;
O interessante é que o banco conecta normal com os parametros originais só quando chamo a consulta fecho o CDS e vou abrir novamente que da este erro de login.
Obrigado pela atenção
Hugo Fabrício
a mensagem é esta : DBexpress Error:Invalid Username/Password.
Verifiquei a opção que vc me falou e esta setada como True, o comando que estou mandando é este :
SQLDataSet.close;
clientedataset.close;
SQLDataSet.CommandText := ´select * from CLIENTE where LOJA = :Empresa and CODIGO = :codigo´;
SQLDataSet.Params.ParamByName(´Empresa´).AsString:= CDSparametro.fieldbyname(´Empresa´).AsString;
SQLDatatSet.Params.ParamByName(´codigo´).AsString:=´0´+edtnumero.Text;
SQLDataSet.open;
ClienteDataSet.Open;
O interessante é que o banco conecta normal com os parametros originais só quando chamo a consulta fecho o CDS e vou abrir novamente que da este erro de login.
Obrigado pela atenção
Hugo Fabrício
GOSTEI 0
Vinicius2k
11/10/2004
Hugo,
Confesso que nunca vi este erro...
Os parametros User_Name e Password da TSQLConnection estão sendo passados em runtime, ou estão fixos no componente ?
Vc está usando uma conexão nomeada ([b:370090c84a]ConnectionName[/b:370090c84a] da TSQLConnection) ?
Qual o valor da propriedade [b:370090c84a]LoadParamsOnConnect[/b:370090c84a] da TSQLConnection ?
Sobre o seu código, não é necessário abrir o TSQLDataSet, a abertura do CDS irá fazer todo o processo de forma automática, inclusive a transação. E existe uma chamada desnecessária à [b:370090c84a]Params.ParamByName[/b:370090c84a] onde pode ser somente [b:370090c84a]ParamByName[/b:370090c84a].
T+
Confesso que nunca vi este erro...
Os parametros User_Name e Password da TSQLConnection estão sendo passados em runtime, ou estão fixos no componente ?
Vc está usando uma conexão nomeada ([b:370090c84a]ConnectionName[/b:370090c84a] da TSQLConnection) ?
Qual o valor da propriedade [b:370090c84a]LoadParamsOnConnect[/b:370090c84a] da TSQLConnection ?
Sobre o seu código, não é necessário abrir o TSQLDataSet, a abertura do CDS irá fazer todo o processo de forma automática, inclusive a transação. E existe uma chamada desnecessária à [b:370090c84a]Params.ParamByName[/b:370090c84a] onde pode ser somente [b:370090c84a]ParamByName[/b:370090c84a].
ClientDataSet.Close; with SQLDataSet do begin Close; CommandText:= ´select * from CLIENTE where LOJA = :Empresa and CODIGO = :codigo´; ParamByName(´Empresa´).AsString:= CDSparametro.fieldbyname(´Empresa´).AsString; ParamByName(´codigo´).AsString:=´0´+edtnumero.Text; end; ClientDataSet.Open;
T+
GOSTEI 0
Hugofab
11/10/2004
Vinicius,
Estou usando uma conection name, propriedade LoadParamsOnConnect esta setada como false, mas já mudei para true para ver se resolve e nada.
Não estou pedindo para abrir o Sqldataset e esta dando um erro: No mapping for Error code found. Coloco para abrir da o erro de login.
Posso te mandar meu código para você analisar se possível!
Hugo Fabrício
Estou usando uma conection name, propriedade LoadParamsOnConnect esta setada como false, mas já mudei para true para ver se resolve e nada.
Não estou pedindo para abrir o Sqldataset e esta dando um erro: No mapping for Error code found. Coloco para abrir da o erro de login.
Posso te mandar meu código para você analisar se possível!
Hugo Fabrício
GOSTEI 0
Vinicius2k
11/10/2004
Hugo,
Antes de vc postar o código todo...
Vc realmente não deve abrir o SQLDataSet, só o CDS. E quanto ao erro de ´No mapping...´ , lembra deste tópico seu ? http://delphiforum.icft.com.br/forum/viewtopic.php?t=51941
Não seriam as aspas ? E *talvez* sejam elas também a causa do problema de login...
Dê preferencia para esta configuração na TSQLConnection :
[b:ed15915fb1]ConnectionName[/b:ed15915fb1]=[em branco]
[b:ed15915fb1]DriverName[/b:ed15915fb1]=Interbase
[b:ed15915fb1]GetDriverFunc[/b:ed15915fb1]=getSQLDriverINTERBASE
[b:ed15915fb1]LibraryName[/b:ed15915fb1]=dbexpint.dll
[b:ed15915fb1]LoadParamsOnConnect[/b:ed15915fb1]=False
[b:ed15915fb1]VendorLib[/b:ed15915fb1]=fbclient.dll [ou gds32.dll]
Desta forma não é necessário distribuir os dbx*.ini.
T+
Antes de vc postar o código todo...
Vc realmente não deve abrir o SQLDataSet, só o CDS. E quanto ao erro de ´No mapping...´ , lembra deste tópico seu ? http://delphiforum.icft.com.br/forum/viewtopic.php?t=51941
Não seriam as aspas ? E *talvez* sejam elas também a causa do problema de login...
Dê preferencia para esta configuração na TSQLConnection :
[b:ed15915fb1]ConnectionName[/b:ed15915fb1]=[em branco]
[b:ed15915fb1]DriverName[/b:ed15915fb1]=Interbase
[b:ed15915fb1]GetDriverFunc[/b:ed15915fb1]=getSQLDriverINTERBASE
[b:ed15915fb1]LibraryName[/b:ed15915fb1]=dbexpint.dll
[b:ed15915fb1]LoadParamsOnConnect[/b:ed15915fb1]=False
[b:ed15915fb1]VendorLib[/b:ed15915fb1]=fbclient.dll [ou gds32.dll]
Desta forma não é necessário distribuir os dbx*.ini.
T+
GOSTEI 0
Hugofab
11/10/2004
Não estou conseguindo fazer esta consulta,
Coloquei (´´) aspas mudei os parâmetros, mas nada, não funciona.
Realmente a coisa ta difícil...
Caso consiga resolver este problema podemos postar este exemplo no site clube delphi para que outros usuários possam usar e não passar a canseira que estou passando.
Pois não encontrei nenhum exemplo de pesquisa desta forma.
Hugo Fabrício
Coloquei (´´) aspas mudei os parâmetros, mas nada, não funciona.
Realmente a coisa ta difícil...
Caso consiga resolver este problema podemos postar este exemplo no site clube delphi para que outros usuários possam usar e não passar a canseira que estou passando.
Pois não encontrei nenhum exemplo de pesquisa desta forma.
Hugo Fabrício
GOSTEI 0
Vinicius2k
11/10/2004
Zipa os fontes e, se quiser, o banco (apropósito qual a versão do Firebird ?) e me manda por e-mail : vncsoliveira[a]gmail.com
Talvez vendo o ´trem´ de perto eu consiga achar alguma coisa...
T+
Talvez vendo o ´trem´ de perto eu consiga achar alguma coisa...
T+
GOSTEI 0
Christian_adriano
11/10/2004
Caro Hugofab,
Tenta fazer o seguinte, com o ´DataSetProvider´ sete a opção ´poAllowCommandText´ pata ´TRUE´ e faça as consultas pelo CDS na propriedade ´CommandText´.
Apos a consulta desejada, se vc quizer retornar a consulta do ´TSQLDataSet´ é só vc fechar o CDS e atribuir ´´ (vazio) para a propriedade ´CommandText´ do CDS.
Tipo:
[b:5a3097b526]Consulta com cds[/b:5a3097b526]
with cds do begin
Close;
CommandText := ´Select ....´;
Open;
end;
[b:5a3097b526]Retornar a Consulta do TSQLDataSet:[/b:5a3097b526]
with cds do begin
Close;
CommandText := ´´;
Open;
end;
espero ter ajudado.
[]´s.
Christian.
Tenta fazer o seguinte, com o ´DataSetProvider´ sete a opção ´poAllowCommandText´ pata ´TRUE´ e faça as consultas pelo CDS na propriedade ´CommandText´.
Apos a consulta desejada, se vc quizer retornar a consulta do ´TSQLDataSet´ é só vc fechar o CDS e atribuir ´´ (vazio) para a propriedade ´CommandText´ do CDS.
Tipo:
[b:5a3097b526]Consulta com cds[/b:5a3097b526]
with cds do begin
Close;
CommandText := ´Select ....´;
Open;
end;
[b:5a3097b526]Retornar a Consulta do TSQLDataSet:[/b:5a3097b526]
with cds do begin
Close;
CommandText := ´´;
Open;
end;
espero ter ajudado.
[]´s.
Christian.
GOSTEI 0
Christian_adriano
11/10/2004
Hugofab,
uma correção boba... hehe
Esqueci que estavamos trabalhando com TClientDataSet, qnado vc altera a opição ´poAllowCommandText´ do ´DataSetProvider´ para True, todos os comando SQL da propriedade CommandText do CDS vão ser atribuido a propriedade CommandText do TSQLDataSet ou TSQLQuery.
Então para ´Retornar a Consulta do TSQLDataSet´ vc tem duas formas de fazer :
1ª - Guardar o Select do TSQLDataSet em alguma variavel para usa-la mais tarde.
2ª - Refazer o commando SQL novamente.
blz ??
flw
[]´s.
Christian.
uma correção boba... hehe
Esqueci que estavamos trabalhando com TClientDataSet, qnado vc altera a opição ´poAllowCommandText´ do ´DataSetProvider´ para True, todos os comando SQL da propriedade CommandText do CDS vão ser atribuido a propriedade CommandText do TSQLDataSet ou TSQLQuery.
Então para ´Retornar a Consulta do TSQLDataSet´ vc tem duas formas de fazer :
1ª - Guardar o Select do TSQLDataSet em alguma variavel para usa-la mais tarde.
2ª - Refazer o commando SQL novamente.
blz ??
flw
[]´s.
Christian.
GOSTEI 0
Hugofab
11/10/2004
Vinicius,
Demorou, mas consegui resolver o problema.
Seguindo as dicas que me passou, funcionou correto,
Obrigado,
Hugo Fabrício!
Demorou, mas consegui resolver o problema.
Seguindo as dicas que me passou, funcionou correto,
Obrigado,
Hugo Fabrício!
GOSTEI 0