Tal y como respondi en DelphiAccess:
El componente internamente interpreta la sentencia SQL y crea automaticamente los parametros; no hace falta que invoques para nada al metodo Parameters.AddParameter
Osea por ejemplo, con un SQL asi:
Código Delphi
[-]
ADOQuery.SQL.Add(...)
ADOQuery.SQL.Add(' WHERE Campo = :Param ');
ADOQuery.Parameters.ParamByName('Param') --> devuelve el TParameter correspondiente
Se crea automaticamente un objeto TParameter con nombre o "identificador" 'Param'.
Si por algun motivo te interesa desactivar esto ultimo y encargarte vos mismo de crear los parametros, debes setear la propiedad
ParamCheck a False
El problema son los parametros pero por ambiguedad; internamente la coleccion TParameters del TADOQuery va a tener dos parametros llamados igual y uno va a quedar sin un valor definido y por eso tiene conflicto de datos
Prueba de concepto (necesario que el ADOQuery tenga su propiedad Connection seteada a una conexion "valida")
Código Delphi
[-]
procedure TForm1.FormCreate(Sender: TObject);
var
Param: TParameter;
begin
ADOQuery1.SQL.Text := ' SELECT * FROM Clientes WHERE Nombre = :Nombre ';
Param := ADOQuery1.Parameters.AddParameter;
Param.Name := 'Nombre';
Param.DataType := TFieldType.ftInteger;
ShowMessage(ADOQuery1.Parameters.Count.ToString); if ADOQuery1.Parameters.ParamByName('Nombre') <> Param then ShowMessage('son distintos objetos');
end;