Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Marcelo Leão

objeto parameter definido incorretamente - ADO

Recommended Posts

Pessoal, estou tentando executar uma simples query com definição de um parâmetro, utilizando o componente ADOQuery e está retornando o seguinte erro: Objeto parameter definido incorretamente. As informações são inconsistentes ou incompletas.

 

Abaixo a query:

 

ADOQuery1.sql.Clear;
ADOQuery1.sql.Add('select * from uscn1');
ADOQuery1.sql.Add('where cduser = :cduser and substring(cduser, 1,1) = substring(:cduser, 1,1)');
ADOQuery1.parameters.parambyname('cduser').DataType := ftstring;
ADOQuery1.parameters.parambyname('cduser').value := 'MARCELO';
ADOQuery1.open;
Notas:
O que está provocando este erro é porque eu preciso utilizar mais de uma vez o mesmo parâmetro (:cduser) na query. Esta query simples eu fiz somente para provocar o erro, a condição Where que eu coloquei não faz muito sentido, mas existem situações principalmente em querys aninhadas que precisamos utilizar mais de uma vez o mesmo parâmetro.
Debuguando o sistema observei que o conteúdo do parâmetro :cduser ('MARCELO') só está sendo passado para o primeiro :cduser encontrado na query, a segunda ocorrência do :cduser não está recebendo a string 'MARCELO'.
No BDE não ocorre isso. As duas ocorrências de :cduser recebem a string 'MARCELO'.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso provavelmente acontece porque, apesar de você usar o mesmo nome no seu sql para o parâmetro, o compilador o interpreta como dois parâmetros de entrada, gerando o erro citado... para resolver este problema, sugiro que monte em uma string todo o select e depois apenas o adicione ao seu ADOQuery antes de dar o Open, fazendo os ajustes necessários no código para isso...

 

 

Só complementando... este link (http://www.borlandtalk.com/adodataset-query-parameter-used-twice-in-the-sql-satatement-vt25721.html) confirma o que falei... apesar de ser o mesmo nome, pro componente eles são dois parâmetros distintos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Chrnos,

 

o que você sugere então é substituir o parâmetro :cduser pelo próprio conteúdo, ou seja concatenar a variável do tipo string que contém o usuário 'MARCELO' com o texto da query. Exemplo: ' where cduser = ' + Variavel + 'and substring(cduser, 1,1) = substring(' + Variavel + ', 1,1) ' .

Se for esta solução, que eu já havia pensado, então não é possível utilizar a criação de parâmetros no ADO nesta situação onde é necessário a reutilização do mesmo parâmetro na query. Isto é horrível, porque nós temos vários sistemas com diversas querys reutilizando parâmetros que com o BDE funciona perfeitamente. Estamos tentando eliminar o BDE e migrar para ADO e seria muito trabalhoso substituir todos os parâmetros por variáveis.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pelo que eu li na pesquisa rápida que fiz, o ADO considera cada entrada de parâmetro como um objeto distinto e, ao enviar o comando via ParamByName para atribuir o valor, a classe retorna o primeiro dos objetos (ou parâmetro) encontrado e preenche no mesmo o valor inserido. Ou seja, para o ADO o mesmo nome passado como parâmetro gera dois ou mais parâmetros de entrada distintos... você poderia resolver o problema usando uma das soluções abaixo:

 

Considerando que tenha 2 parâmetros apenas na consulta (este estou fazendo de cabeça, não lembro com certeza se a sintaxe é assim):

 

 

ADOQuery1.Parameters[0].DataType := ftstring;
ADOQuery1.Parameters[0].value := 'MARCELO';

ADOQuery1.Parameters[1].DataType := ftstring;
ADOQuery1.Parameters[1].value := 'MARCELO';


E laia, o fórum comeu um pedaço do meu post ¬¬

 

Complementando então.... no fórum da Embarcadero, há este post (http://qc.embarcadero.com/wc/qcmain.aspx?d=1654) sobre o tema, onde ele dá uma sugestão baseado no SQL Server que talvez possa resolver o seu problema... de todo modo, terá que rever e definir a melhor maneira de migrar suas consultas para o ADO.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal obrigado pelas dicas. Li o post do site Embarcadero e vamos analisar qual das duas soluções do site é a mais viável. Pensei em uma terceira que seria a criação de uma procedure no delphi que recebesse o componente AdoQuery com o SQL e os valores dos parâmetros já setados. Seria feito então um loop para identificar parâmetros com nomes idênticos e então igualar as propriedades value e datatype do primeiro parâmetro às do segundo parâmetro de mesmo nome.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não seria talvez mais simples levar os selects para procedures dentro do BD e simplesmente chamar a procedure pelo delphi? Deixar as regras de negócio no BD?

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.