Consultas con variables en una bd?

Hola, estoy tratando de realizar una consulta en una base de datos sqlite que evalua si un campo es igual a una variable,
pero pensé que se hacia con prepared y bindValue. Pero me genera un error, explico el código:

 idconsulta = 1;
            qDebug()<<"id"<<idconsulta;
 
            QSqlQuery consulta;
            consulta.prepare("select * from lamparas where id = (:idconsulta) order by id desc limit 1");
            consulta.bindValue(":idconsulta", idconsulta);
            consulta.exec();

Este es el código que tengo para la consulta y compila, pero cuando ejecuto la consulta me muestra el siguiente error:

QSqlQuery::value: not positioned on a valid record

¿Como puedo hacer para ejecutar las consultas evaluando valores de variables?

Gracias

hola..bueno

bueno te comento que a mi me ha dado varios problemas cuando uso un colector de esos en media consulta y no al final.

o sea, cuando uso una expresión como "select tal,cual from tabla where id=:colector order by desc limit" suele darme problemas el query.

a distincion de usar solo : "select tal,cual from tabla where id=:colector"

oye, no se si tu consulta este mala. pero puedes optar por otra forma de armar tus consultas.

asi:

QString qu=tr("select * from lamparas where id = '%1' order by id desc limit 1").arg(idconsulta);

luego

QSqlQuery query;
query.exec(qu);

ese metodo suele darme mejores resultados que usar los colectores y el metodo bindvalue.

otra cosa es que tal vez, necesites acompañar o encerrar en apostrofes el colector dentro de la consulta:
':idconsulta'

a veces por no usar eso me daba errores.

salu2

me parece bien...

Me parece bien realizar asi mis consultas de la forma que me sugieres, pero ¿Podrias explicarme? para que utilizo el (='%1') y en el final de la consulta .arg(idconsulta)?
No entiendo bien con que fin se hace de esa forma...
Muchas gracias. saludos!

bueno. en realidad es como

bueno. en realidad es como usar el %s dentro del printf de c++.
printf("el nombre es %s ",objeto.nombre);
recuerdas? como para ubicar alli el valor que pasas usando el metodo arg de tr.

tr en realidad es una funcion global en qt para las traducciones de las cadenas de texto. y devuelve una cadena de texto traducida en caso de que hayamos preparado todo para hacer las traducciones dentro de nuestra aplicacion. pero como eso no se hace en tu programa unicamente retorna la cadena de texto pasada mas los valores que le pasa con el metodo arg.

asi sin importar donde necesites ubicar un valor variable podras usar eso.

si son varios valores se haria asi:

tr("select tal cosa where id='%1' and nombre='%2').arg(variable1,variable2);

y asi para la cantidad de variables que se usen, aunque se que existe un limite. solo que ni idea de cual es.

Los paréntesis dentro de la sentencia no son necesarios

Elimina los paréntesis de tu sentencia

consulta.prepare("select * from lamparas where id=:idconsulta order by id desc limit 1");

Cuando te genera el error de "not positioned on a valid record", se refiere a que, o bien no se ha generado ningún resultado tras la ejecución de la sentencia SQL (esto es, la sentencia de búsqueda no ha devuelto ningún resultado), o que no has avanzado el puntero interno de la sentencia a ningún registro válido; puedes comprobarlo llamando al método first() o al método next(), y la validez del registro utilizando el método isValid().

// Ejemplo de bucle para recorrer resultados en una QSqlQuery ejecutada con exito
 
if(!query.exec()) {
  QMessageBox::warning(this,tr("Problema con sentencia"),tr("No se pudo ejecutar la 
  sentencia"),QMessageBox::Ok);
}
 
else {
 while(query.next()) {
   if(query.isValid()) {
    /// Operamos con los resultados de la sentencia
   }
 }
}

Lo mejor es que compruebes siempre si la sentencia se ha ejecutado con éxito, y luego compruebes si el registro en el que te posicionas es un registro válido.

¡Un saludo!

bien! pero...

Muchas gracias, la consulta me funciona comprobando el registro con next().
Quisiera preguntar si es posible lo siguiente:

Si quiero que en la consulta no se ejecute solo ( where id=:idconsulta ), sino que sea donde idconsulta -1, osea una pocision anterior.
Yo se que puedo utiluzar una variable con el valor de idconsulta -1, y luego realizar la consulta con la variable. Pero resulta que estas operaciones las tengo dentro de un Qtimer, y asi me genera datos erroneos, porque necesito que esta resta se haga una vez.
pero¿Se puede utilizar los operasores matématicos en las consultas? ¿Como se haria?..

Gracias por tu respuesta! Espero me puedan aclarar este punto

Prueba así

consulta.prepare("select * from lamparas where id= (:idconsulta - 1) order by id desc limit 1");

No estarías realizando la operación dentro del código de tu programa, sino que sería el gestor de base de datos el que se encargaría de la operación matemática, aunque no sé si así vas a resolver el problema, ya que la sentencia se lanzará cada vez que se vuelva a llamar al bucle del QTimer, si he entendido bien; además, también depende de cómo trabaje Qt 4 con el método bindValue(), si añade o no comillas al valor que estás vinculando, y también del comportamiento del gestor de bases de datos sobre el que estés trabajando.

¡Un saludo!

Anuncios Google