QSqlTableModel не удаётся редактировать и удалять данные
Добрый день.
Впервые решил использовать для создания базы данных связку модели и представления. За основу взял SQLite. Класс Model унаследован от QSqlTableModel. Способ подключения базы данных и связки модели с представлением взял с этого сайта, немного изменив. Но, к сожалению, не работает обновление данных и удаление. Чтобы я ни делал, не получается. Может кто-нибудь знает решение?
Вот этот метод работает:
bool Model::save_to_db(Data *item) { QSqlQuery query; query.setForwardOnly(true); query.prepare("INSERT INTO myDB (code, date, person, description)" "VALUES (:code, :date, :person, :description)"); query.bindValue(":code", item->Code()); query.bindValue(":date", item->Date()); query.bindValue(":person", item->Person()); query.bindValue(":description", item->Description()); if(query.exec()) return true; qCritical() << query.lastError().databaseText(); qCritical() << query.lastError().driverText(); qCritical() << query.lastError().nativeErrorCode(); return false; }
Вот этот не работает (данные добавляются в представление, но не в базу):
bool Model::update_in_db(Data *item) { QSqlQuery query; query.setForwardOnly(true); query.prepare("UPDATE myDB SET \n" " code = :code, \n" " date = :date, \n" " person = :person, \n" " description = :description \n" "WHERE id = :id; \n" ); query.bindValue(":code", item->Code()); query.bindValue(":date", item->Date()); query.bindValue(":person", item->Person()); query.bindValue(":description", item->Description()); if(query.exec()) { return true; } else { qCritical() << query.lastError().databaseText(); qCritical() << query.lastError().driverText(); qCritical() << query.lastError().nativeErrorCode(); return false; } }
И удаление не работает:
Model::delete_from_db() { QSqlQuery query; query.setForwardOnly(true); query.prepare("DELETE FROM myDB WHERE id = :ID ;"); query.bindValue(":ID", currentIndex.row());//индекс сигналом по клику //передаю из MainWindow, так как представление находится в классе MainWindow if(!query.exec()){ qCritical() << query.lastError().databaseText().toUtf8().data(); qCritical() << query.lastError().driverText(); qCritical() << query.lastError().nativeErrorCode(); return false; } else { return true; } return false; }
Спасибо за внимание!
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!
Пікірлер
- Akiv Doros
- Қар. 11, 2024, 2:58 Т.Қ.
C++ - Тест 004. Указатели, Массивы и Циклы
- Нәтиже:50ұпай,
- Бағалау ұпайлары-4
- molni99
- Қаз. 26, 2024, 1:37 Т.Ж.
C++ - Тест 004. Указатели, Массивы и Циклы
- Нәтиже:80ұпай,
- Бағалау ұпайлары4
- molni99
- Қаз. 26, 2024, 1:29 Т.Ж.
C++ - Тест 004. Указатели, Массивы и Циклы
- Нәтиже:20ұпай,
- Бағалау ұпайлары-10
Добрый день.
Метод update_in_db скорее всего не работает из-за наличия знаков каретки \n , а также из-за того, что нет bind для ID.
Что касается delete_from_db , то тут я не уверен, в чём может быть ошибка. Что вываливается в вывод qCritical?
Да, редактирование теперь работает! Спасибо!
По поводу удаления, причина в том, что индекс в представлении отличается от id в базе. Нужно брать id для удаления из базы, а не из представления. Всё, задача решена!
Если через раз, то дело скорее всего в том, что обычно ID является автоинкрементируемым столбцом, который всегда растёт, даже если какие-то строки удалялись из базы данных. Если у вас было 4 записи с ID: 1, 2, 3, 4 и вы удалили 4-й, то следующий ID будет 5 и в таблице будут 1, 2, 3, 5.
В данном случае currentIndex.row() не отвечает ID, это просто номер строки в таблице. Вам нужно сначала получить ID записи, можно это сделать через метод data, просто нужно иметь столбки с ID, можно сделать его скрытым. А потом уже делать удаление по этому id
А удаление всё же не работает. Понял это когда по аналогии с этим проектом создал проект с картинками. При удалении элементов размер базы данных не меняется. То есть в представлении элемент показываться не будет, но из базы данных по видимому не удаляется.
а проверить просто что находится в базе? и вообще SQLite, на сколько помню, удаляет данные из поля, чтоб изменить размер и удалить пустые строки нужно доболнительно делать вакуум