CheckBox suma
-
Hola, estoy haciendo una aplicación bastante simple con sqlite y una lista con checkbox y necesitas guardar las faltas de los alumnos. Cuando hago el for para recorrer los checkbox y después actualizo la base de datos, me suma la misma cantidad de alumnos ausentes en cada uno de los campos, es decir que acumula y suma. Como puedo hacer para que me sume 1 por cada fila?
Este es el coding de las dos funciones:void MainWindow::chequedState(int i){ if (ui->listWidget->item(i)->checkState() == Qt::Unchecked) { QSqlQuery update; update.bindValue(":id", i); update.prepare("UPDATE alumnos SET faltas = faltas + 1 WHERE id"); update.exec(); } }
/void MainWindow::saveAssistence() { int rowCount = ui->listWidget->count(); for (int i = 0; i < rowCount; i++) { chequedState(i); } }
Gracias!
-
Hola @Aioria
Creo que tienes mal la query, tienes que llamar a prepare antes de bindValue, además te faltó añadir el parámetro ID en la query
QSqlQuery update; update.prepare("UPDATE alumnos SET faltas = faltas + 1 WHERE id = :id"); update.bindValue(":id", i); update.exec();
Desconozco si faltas = faltas + 1 funciona como esperas, revisa la documentación de SQLite para comprobarlo.
Además, puedes usar el valor de retorno de exec y lastError para comprobar si te da algún error la query y así puedes ver si funciona como esperas.
Un saludo
-
Hola @juanki No encontré diferencia al cambiar eso de lugar. El tema es que pruebo con el =:id y no hace nada. Así como lo tengo me suma tantas faltas como tantas checkbox tenga sin checkear. La idea seria que me sume 1 solo a las casillas que no están chequeadas.
-
Hola
¿Comprobaste si obtienes algún error? Si no hace nada es posiblemente por que hay algún error en la consulta o por que no hay ningún ID que coincida con el que buscas.
Cuando haces un update tienes que indicar qué registro quieres actualizar, por eso el = :id, para que actualize solo el ID que quieres.
Comprueba también el ID que intentas actualizar (puedes simplemente imprimirlo por consola).
Un saludo
-
Hola
Qt es C++, por tanto puedes usar cualquier cosa de C++, por ejemplo cout, aunque personalmente uso QDebug para ir mostrando mensajes cuando estoy probando o depurando el programa.
A parte de esto, estás haciendo un bucle en el que a cada vuelta haces un update, puedes usar execBatch para hacer todo de una vez. Lo he probado con inserts, nunca con update, aunque supongo que funcionará igual, no vi nada en contra en la documentación (aunque mi inglés es muy malo :P).
Otra opción es ver si en la cláusula WHERE puedes incluir diferentes ID, así haces todo con un único update. Mira la documentación de SQLite para ver las opciones que tienes,
Un saludo
-
@juanki Claro, me fijo si devuelve bien el i y parece correcto. Lo mismo con el Id, la suma le la hace y recorre bien la tabla y las checkbox.
Se que el problema esta en el for, porque me cuenta primero las checkbox que no están chequeadas y luego me las actualiza todas al mismo tiempo, pero no se me ocurre como puedo hacer para que no pase eso -
Hola
Pues no se. Es raro que te actualice todos. Te va a tocar depurar.
Ve imprimiendo en consola a cada ciclo del bucle la ID que te manda a actualizar.
El campo ID de la base de datos sera de tipo int ¿no?
Prueba la consulta con un gestor de bases de datos.Imagino que estás usando "where id = :id" como te dije, por que si no te los actualiza todos.
Un saludo
-
@juanki
Yo creo que tiene que ser problema del id como decís vos. Como hago para mostrar el valor del id de la base de datos para asegurarme que es lo que esta fallando? O sea, ir mostrando que valor va teniendo el id dentro del for.
Sisi, ya lo cambie y quedo con :id y no hace nada, por lo que seguramente es eso, pero quiero asegurarme. Y después ver como hacer para que el id tenga el mismo valor que el i del for -
Hola
Viendo el código ahora me fijo que a la id le estás pasando el índice de un bucle for, que no tiene por qué coincidir con los id que tienes guardados.
Tienes que cargar los datos de la base de datos y usarlos para mostrar la lista y luego saber cuál se seleccionó o no para actualizar la base de datos.
Perdón si me explico mal, estoy de viaje con el móvil solo.
Un saludo
-
@Pablo-J.-Rogina
Si, aca es donde creo la tabla:void MainWindow::CreateStudentTable() { QSqlQuery consult; consult.prepare("CREATE TABLE IF NOT EXISTS alumnos(" "id INTEGER PRIMARY KEY AUTOINCREMENT," "nombre VARCHAR(100)," "apellido VARCHAR(100), " "faltas INTEGER NOT NULL" ");"); if(consult.exec()){ qDebug()<<"La tabla ALUMNOS existe."; }else{ qDebug()<<"La tabla ALUMNOS NO existe"; qDebug()<<"ERROR! " << consult.lastError(); }
-
Hola
El problema es que ese i es el índice del for, no tiene por qué coincidir con una id de la bases de datos.
Mírate los modelos, no es muy complejo lo que quieres hacer, con un modelo y un delegate casi seguro que puedes hacerlo.
Un saludo
-
@Aioria said in CheckBox suma:
Tu problema a mi entender, como también otras personas han comentado es que estás usando el nro. de fila de la visualización para actualizar el alumno con ese Id pero eso no es correcto.
id INTEGER PRIMARY KEY AUTOINCREMENT
Con esta definicion por favor recordar que el motor de BD le asigna un valor automáticamente al campo id cada vez que agregas un alumno a la tabla.
Luego en tu visualización, tienes que tomar ese id y no la variable del for() como índice para acceder a la tabla y actualizar las faltas. No tienes un problema de binding de variables si no de valores!!!