Search code examples
qtqt5qtsql

Why do I get false when I try to insert a record to a QSqlTableModel in QT?


I'm creating a QSqlRecord object and then I set the values to that QSqlRecord object. But even if I insert the QSqlRecord object to the QSqlTableModel object, the function of inserting records, returns false.

I have this C++ code and it create a QSqlRecord object and set the values. It setting the values in the correct indexed order as how the table was created.

/* Insert data */
int column_index = 0; /* Index 0 is the ID  column */
QSqlRecord record;
qDebug() << CALIBRATION_COLUMNS.at(column_index).first;
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, 1); /* ID */
qDebug() << CALIBRATION_COLUMNS.at(column_index).first;
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, calibration_id);
qDebug() << CALIBRATION_COLUMNS.at(column_index).first;
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, calibration_comment);
qDebug() << CALIBRATION_COLUMNS.at(column_index).first;
record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, calibration_date_time);
for(int i = 0; i < 12; i++){
    record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, min_adc[i]);
    record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, max_adc[i]);
    record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, bias_adc[i]);
}
for(int i = 0; i < 5; i++){
    record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, min_dadc[i]);
    record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, max_dadc[i]);
    record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, bias_dadc[i]);
}
for(int i = 0; i < 2; i++)
    record.setValue(CALIBRATION_COLUMNS.at(column_index++).first, pulses_per_revolution_encoder[i]);

/* -1 means append record */
qDebug() << calibration_model->insertRecord(-1, record);
qDebug() << calibration_model->lastError().text();
qDebug() << "Submit:";
if(!calibration_model->submitAll()){
    qDebug() << calibration_model->lastError().text();
    return DATABASE_STATUS_COULD_NOT_INSERT_ROW;
}
return DATABASE_STATUS_OK;

But even if I insert the record, this function calibration_model->insertRecord(-1, record); returns false but the calibration_model->submitAll() returns true.

Output:

"ID"
"calibration_id"
"calibration_comment"
"calibration_date_time"
false
"No Fields to update"
Submit:

So tell me. What I'm I doing wrong here?

I'm getting the error No Fields to update, but what does that mean? I have an empty table and I just want to append with one row.


Solution

  • Not sure why you're getting that error. I have a small example for QSqlTableModel. Let me put it here. Maybe you could compare with your code.

    main.cpp

    #include <QApplication>
    #include "mysqltablemodel.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("mydb");
    
        if(!db.open()) {
            qDebug() << db.lastError().text();
            return 0;
        }
    
        QSqlQuery query(db);
    
        if(!query.exec("DROP TABLE IF EXISTS mytable")) {
            qDebug() << "create table error: " << query.lastError().text();
            return 0;
        }
    
        if(!query.exec("CREATE TABLE IF NOT EXISTS mytable \
                       (id integer primary key autoincrement, name varchar(15), salary integer)")) {
            qDebug() << "create table error: " << query.lastError().text();
            return 0;
        }
    
        MySqlTableModel *model = new MySqlTableModel(0, db);
        model->setTable("mytable");
        model->setEditStrategy(QSqlTableModel::OnManualSubmit);
        model->select();
    
        QSqlRecord rec = model->record();
        rec.setValue(1, "peter");
        rec.setValue(2, 100);
        qDebug() << model->insertRecord(-1, rec);
        rec.setValue(1, "luke");
        rec.setValue(2, 200);
        qDebug() << model->insertRecord(-1, rec);
    
        if(model->submitAll()) {
            model->database().commit();
        } else {
            model->database().rollback();
            qDebug() << "database error: " << model->lastError().text();
        }
    
        query.exec("SELECT name, salary FROM mytable");
    
        while (query.next()){
            QString name = query.value(0).toString();
            int salary = query.value(1).toInt();
            qDebug() << name << salary;
        }
    
        return app.exec();
    }
    

    mysqltablemodel.h

    #ifndef MYSQLTABLEMODEL_H
    #define MYSQLTABLEMODEL_H
    
    #include <QSqlTableModel>
    #include <QSqlRecord>
    #include <QSqlError>
    #include <QSqlQuery>
    #include <QDebug>
    
    class MySqlTableModel : public QSqlTableModel
    {
        Q_OBJECT
    
    public:
        MySqlTableModel(QObject *parent = 0, QSqlDatabase db = QSqlDatabase());
        QVariant data(const QModelIndex &index, int role=Qt::DisplayRole ) const;
    
    protected:
        QHash<int, QByteArray> roleNames() const;
    
    private:
        QHash<int, QByteArray> roles;
    };
    
    #endif // MYSQLTABLEMODEL_H
    

    mysqltablemodel.cpp

    #include "mysqltablemodel.h"
    
    MySqlTableModel::MySqlTableModel(QObject *parent, QSqlDatabase db): QSqlTableModel(parent, db) {}
    
    QVariant MySqlTableModel::data ( const QModelIndex & index, int role ) const
    {
        if(index.row() >= rowCount()) {
            return QString("");
        }
        if(role < Qt::UserRole) {
            return QSqlQueryModel::data(index, role);
        }
        else {
            return QSqlQueryModel::data(this->index(index.row(), role - Qt::UserRole), Qt::DisplayRole);
        }
    }
    
    QHash<int, QByteArray> MySqlTableModel::roleNames() const
    {
        QHash<int, QByteArray> roles;
        roles[Qt::UserRole + 1] = "name";
        roles[Qt::UserRole + 2] = "salary";
        return roles;
    }