Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Insert record into QSqlTableModel

Insert record into QSqlTableModel

Scheduled Pinned Locked Moved Solved General and Desktop
52 Posts 5 Posters 10.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ JonB

    @tovax said in Insert record into QSqlTableModel:

    I just tested 10000 rows, and it took 160 seconds to insert a row, which is really too long.

    Wot??!! :D So what database are you actually using? Is it SQLite? Elsewhere someone was telling me that it has some "in-memory" setting so it can be "really fast"?

    3 minutes is crazy! Purely for my own/your information, do you feel like testing that suggestion I made of a single SQL statement

    UPDATE table SET rowNumColumn = rowNumColumn + 1 WHERE rowNumColumn >= rowNumToInsert
    

    ? I'd be interested to hear how that performs!?

    tovaxT Offline
    tovaxT Offline
    tovax
    wrote on last edited by
    #41

    @JonB
    Only 108ms.

    UPDATE table SET rowNumColumn = rowNumColumn - 1
    
    JonBJ jsulmJ 2 Replies Last reply
    0
    • tovaxT tovax

      @JonB
      Only 108ms.

      UPDATE table SET rowNumColumn = rowNumColumn - 1
      
      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by JonB
      #42

      @tovax
      LOL! See what I meant by suggesting that would be much quicker than updating rows by sending each one to the database? :) 1/10th of a second instead of 160 seconds!

      So, at some level, if time is critical, you could find a way to exploit this. Maybe something like: use the 10-gap numbering we discussed. While that has a gap for your insert, fine. If you do need to "renumber": instead of updating each record, send that (or some other appropriate) SQL statement to the database, and just read back in the lines at that point to replace what you had in memory?

      1 Reply Last reply
      1
      • tovaxT tovax

        @JonB
        Only 108ms.

        UPDATE table SET rowNumColumn = rowNumColumn - 1
        
        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #43

        @tovax I'm really wondering why you want to number rows in the database? What is the use case? If it is for showing in the UI then there is no point in adding the row numbers already in the database.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        JonBJ tovaxT 2 Replies Last reply
        0
        • jsulmJ jsulm

          @tovax I'm really wondering why you want to number rows in the database? What is the use case? If it is for showing in the UI then there is no point in adding the row numbers already in the database.

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by JonB
          #44

          @jsulm
          Dear @jsulm, have you read through this whole discussion? :) The whole point is that the OP needs a database table which can do what happens in a spreadsheet/Excel, i.e. rows have an order, rows come before or after each other. Unlike what one normally has to deal with in a relational database, but a perfectly valid question. And the user has to be able to insert/delete rows, with immediate commit to the database, in real time. When you come up with a better suggestion than I have dealing with OP and suggesting how he can impose & manage a row ordering, I should be most interested to hear!

          @tovax
          BTW, I don't think you have ever said which database you are using, just in case it has anything of its own supporting "row order"? SQL itself does not, but you never know what an implementation might add.

          tovaxT 1 Reply Last reply
          0
          • JonBJ JonB

            @jsulm
            Dear @jsulm, have you read through this whole discussion? :) The whole point is that the OP needs a database table which can do what happens in a spreadsheet/Excel, i.e. rows have an order, rows come before or after each other. Unlike what one normally has to deal with in a relational database, but a perfectly valid question. And the user has to be able to insert/delete rows, with immediate commit to the database, in real time. When you come up with a better suggestion than I have dealing with OP and suggesting how he can impose & manage a row ordering, I should be most interested to hear!

            @tovax
            BTW, I don't think you have ever said which database you are using, just in case it has anything of its own supporting "row order"? SQL itself does not, but you never know what an implementation might add.

            tovaxT Offline
            tovaxT Offline
            tovax
            wrote on last edited by
            #45

            @JonB Hi, I am using sqlite3.
            I updated the algorithm based on your reply. In the case of 10,000 rows in the database, now it only takes 600ms to insert or delete a row. But I’m sorry to say that I’m not sure if I really understand what you mean: first renumber the “Rownumber” column of the database directly, then read the database to the tablemodel, and then display the sorted data in the tableview. code show as below:
            Insert:

            void JCDemoDatabase::onInsertClicked()
            {
                // 1 - begin
                QSqlQuery query(database);
                QString sql;
                QElapsedTimer timer;
                timer.start();
            
                int32_t currentRowIndex = tableView->currentIndex().row();
            
                // 2 - update first
                sql.clear();
                sql.append(QStringLiteral("UPDATE %1 SET %2 = -(%2 + 1) WHERE %2 >= %3")
                           .arg(Table::Name)
                           .arg(Table::RowNumber)
                           .arg(currentRowIndex));
                query.prepare(sql);
                if (!query.exec()){
                    QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("1:%1").arg(query.lastError().text()), QMessageBox::Abort);
                    return;
                }
            
                // 3 - update second
                sql.clear();
                sql.append(QStringLiteral("UPDATE %1 SET %2 = -(%2) WHERE %2 < 0")
                           .arg(Table::Name)
                           .arg(Table::RowNumber));
                query.prepare(sql);
                if (!query.exec()){
                    QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("2:%1").arg(query.lastError().text()), QMessageBox::Abort);
                    return;
                }
            
                // 4 - insert
                sql.clear();
                sql.append(QStringLiteral("INSERT INTO %1 (A, B, C, D, E, F, G, H, RowNumber)"
                                          "VALUES (:A, :B, :C, :D, :E, :F, :G, :H, :RowNumber)")
                           .arg(Table::Name));
                query.prepare(sql);
                query.bindValue(":A", QString("---"));
                query.bindValue(":B", QString("---"));
                query.bindValue(":C", QString("---"));
                query.bindValue(":D", QString("---"));
                query.bindValue(":E", QString("---"));
                query.bindValue(":F", QString("---"));
                query.bindValue(":G", QString("---"));
                query.bindValue(":H", QString("---"));
                query.bindValue(":RowNumber", currentRowIndex);
                if (!query.exec()){
                    QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("3:%1").arg(query.lastError().text()), QMessageBox::Abort);
                    // return;
                }
            
                // 5 - end
                query.finish();
                tableModel->select();
                int32_t rowNumberIndex = tableModel->record().indexOf(Table::RowNumber);
                tableModel->sort(rowNumberIndex, Qt::AscendingOrder);
                QMessageBox::information(this, QStringLiteral("Info"), QStringLiteral("Time:%1 ms").arg(timer.elapsed()), QMessageBox::Ok);
            }
            

            Remove:

                // 1 - begin
                QSqlQuery query(database);
                QString sql;
                QElapsedTimer timer;
                timer.start();
            
                int32_t currentRowIndex = tableView->currentIndex().row();
            
                // 2 - remove
                sql.clear();
                sql.append(QStringLiteral("DELETE FROM %1 WHERE %2 = %3")
                           .arg(Table::Name)
                           .arg(Table::RowNumber)
                           .arg(currentRowIndex)
                           );
                query.prepare(sql);
                if (!query.exec()){
                    QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("1:%1").arg(query.lastError().text()), QMessageBox::Abort);
                    // return;
                }
            
                // 3 - update first
                sql.clear();
                sql.append(QStringLiteral("UPDATE %1 SET %2 = -(%2 - 1) WHERE %2 > %3")
                           .arg(Table::Name)
                           .arg(Table::RowNumber)
                           .arg(currentRowIndex));
                query.prepare(sql);
                if (!query.exec()){
                    QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("2:%1").arg(query.lastError().text()), QMessageBox::Abort);
                    return;
                }
            
                // 4 - update second
                sql.clear();
                sql.append(QStringLiteral("UPDATE %1 SET %2 = -(%2) WHERE %2 < 0")
                           .arg(Table::Name)
                           .arg(Table::RowNumber));
                query.prepare(sql);
                if (!query.exec()){
                    QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("3:%1").arg(query.lastError().text()), QMessageBox::Abort);
                    return;
                }
            
                // 5 - end
                query.finish();
                tableModel->select();
                int32_t rowNumberIndex = tableModel->record().indexOf(Table::RowNumber);
                tableModel->sort(rowNumberIndex, Qt::AscendingOrder);
                QMessageBox::information(this, QStringLiteral("Info"), QStringLiteral("Time:%1 ms").arg(timer.elapsed()), QMessageBox::Ok);
            
            JonBJ 1 Reply Last reply
            0
            • jsulmJ jsulm

              @tovax I'm really wondering why you want to number rows in the database? What is the use case? If it is for showing in the UI then there is no point in adding the row numbers already in the database.

              tovaxT Offline
              tovaxT Offline
              tovax
              wrote on last edited by
              #46

              @jsulm Hi, Maybe I didn't express enough. The records in this database are arranged in order, such as the motor trajectory of CNC machine tools.
              Best regards!

              1 Reply Last reply
              0
              • tovaxT tovax

                @JonB Hi, I am using sqlite3.
                I updated the algorithm based on your reply. In the case of 10,000 rows in the database, now it only takes 600ms to insert or delete a row. But I’m sorry to say that I’m not sure if I really understand what you mean: first renumber the “Rownumber” column of the database directly, then read the database to the tablemodel, and then display the sorted data in the tableview. code show as below:
                Insert:

                void JCDemoDatabase::onInsertClicked()
                {
                    // 1 - begin
                    QSqlQuery query(database);
                    QString sql;
                    QElapsedTimer timer;
                    timer.start();
                
                    int32_t currentRowIndex = tableView->currentIndex().row();
                
                    // 2 - update first
                    sql.clear();
                    sql.append(QStringLiteral("UPDATE %1 SET %2 = -(%2 + 1) WHERE %2 >= %3")
                               .arg(Table::Name)
                               .arg(Table::RowNumber)
                               .arg(currentRowIndex));
                    query.prepare(sql);
                    if (!query.exec()){
                        QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("1:%1").arg(query.lastError().text()), QMessageBox::Abort);
                        return;
                    }
                
                    // 3 - update second
                    sql.clear();
                    sql.append(QStringLiteral("UPDATE %1 SET %2 = -(%2) WHERE %2 < 0")
                               .arg(Table::Name)
                               .arg(Table::RowNumber));
                    query.prepare(sql);
                    if (!query.exec()){
                        QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("2:%1").arg(query.lastError().text()), QMessageBox::Abort);
                        return;
                    }
                
                    // 4 - insert
                    sql.clear();
                    sql.append(QStringLiteral("INSERT INTO %1 (A, B, C, D, E, F, G, H, RowNumber)"
                                              "VALUES (:A, :B, :C, :D, :E, :F, :G, :H, :RowNumber)")
                               .arg(Table::Name));
                    query.prepare(sql);
                    query.bindValue(":A", QString("---"));
                    query.bindValue(":B", QString("---"));
                    query.bindValue(":C", QString("---"));
                    query.bindValue(":D", QString("---"));
                    query.bindValue(":E", QString("---"));
                    query.bindValue(":F", QString("---"));
                    query.bindValue(":G", QString("---"));
                    query.bindValue(":H", QString("---"));
                    query.bindValue(":RowNumber", currentRowIndex);
                    if (!query.exec()){
                        QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("3:%1").arg(query.lastError().text()), QMessageBox::Abort);
                        // return;
                    }
                
                    // 5 - end
                    query.finish();
                    tableModel->select();
                    int32_t rowNumberIndex = tableModel->record().indexOf(Table::RowNumber);
                    tableModel->sort(rowNumberIndex, Qt::AscendingOrder);
                    QMessageBox::information(this, QStringLiteral("Info"), QStringLiteral("Time:%1 ms").arg(timer.elapsed()), QMessageBox::Ok);
                }
                

                Remove:

                    // 1 - begin
                    QSqlQuery query(database);
                    QString sql;
                    QElapsedTimer timer;
                    timer.start();
                
                    int32_t currentRowIndex = tableView->currentIndex().row();
                
                    // 2 - remove
                    sql.clear();
                    sql.append(QStringLiteral("DELETE FROM %1 WHERE %2 = %3")
                               .arg(Table::Name)
                               .arg(Table::RowNumber)
                               .arg(currentRowIndex)
                               );
                    query.prepare(sql);
                    if (!query.exec()){
                        QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("1:%1").arg(query.lastError().text()), QMessageBox::Abort);
                        // return;
                    }
                
                    // 3 - update first
                    sql.clear();
                    sql.append(QStringLiteral("UPDATE %1 SET %2 = -(%2 - 1) WHERE %2 > %3")
                               .arg(Table::Name)
                               .arg(Table::RowNumber)
                               .arg(currentRowIndex));
                    query.prepare(sql);
                    if (!query.exec()){
                        QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("2:%1").arg(query.lastError().text()), QMessageBox::Abort);
                        return;
                    }
                
                    // 4 - update second
                    sql.clear();
                    sql.append(QStringLiteral("UPDATE %1 SET %2 = -(%2) WHERE %2 < 0")
                               .arg(Table::Name)
                               .arg(Table::RowNumber));
                    query.prepare(sql);
                    if (!query.exec()){
                        QMessageBox::critical(this, QStringLiteral("Error"), QStringLiteral("3:%1").arg(query.lastError().text()), QMessageBox::Abort);
                        return;
                    }
                
                    // 5 - end
                    query.finish();
                    tableModel->select();
                    int32_t rowNumberIndex = tableModel->record().indexOf(Table::RowNumber);
                    tableModel->sort(rowNumberIndex, Qt::AscendingOrder);
                    QMessageBox::information(this, QStringLiteral("Info"), QStringLiteral("Time:%1 ms").arg(timer.elapsed()), QMessageBox::Ok);
                
                JonBJ Online
                JonBJ Online
                JonB
                wrote on last edited by JonB
                #47

                @tovax said in Insert record into QSqlTableModel:

                I updated the algorithm based on your reply. In the case of 10,000 rows in the database, now it only takes 600ms to insert or delete a row.

                Great! Isn't that an improvement? :)

                But I’m sorry to say that I’m not sure if I really understand what you mean: first renumber the “Rownumber” column of the database directly, then read the database to the tablemodel

                You start with a model with certain row numbers in each row. When you execute an UPDATE table SET rowNumColumn = rowNumColumn - 1-type statement the row numbers potentially change in any number of the rows you currently have in your read-in table model, making that now not up-to-date; but Qt infrastructure does not know that you have made this change to many other rows. So, you need to re-read the rows into the model to ensure they reflect the new situation. In your code, after update-renumbering, I see you have:

                tableModel->select();
                

                That does indeed read the rows into the model afresh, so I think your code does exactly what is wanted. Verify that after this your tableModel row contents now do indeed have the correctly renumbered row number values?

                tovaxT 1 Reply Last reply
                1
                • JonBJ JonB

                  @tovax said in Insert record into QSqlTableModel:

                  I updated the algorithm based on your reply. In the case of 10,000 rows in the database, now it only takes 600ms to insert or delete a row.

                  Great! Isn't that an improvement? :)

                  But I’m sorry to say that I’m not sure if I really understand what you mean: first renumber the “Rownumber” column of the database directly, then read the database to the tablemodel

                  You start with a model with certain row numbers in each row. When you execute an UPDATE table SET rowNumColumn = rowNumColumn - 1-type statement the row numbers potentially change in any number of the rows you currently have in your read-in table model, making that now not up-to-date; but Qt infrastructure does not know that you have made this change to many other rows. So, you need to re-read the rows into the model to ensure they reflect the new situation. In your code, after update-renumbering, I see you have:

                  tableModel->select();
                  

                  That does indeed read the rows into the model afresh, so I think your code does exactly what is wanted. Verify that after this your tableModel row contents now do indeed have the correctly renumbered row number values?

                  tovaxT Offline
                  tovaxT Offline
                  tovax
                  wrote on last edited by
                  #48

                  @JonB Yes, all contents and functions are correct. Thank you again.
                  Best regards!

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #49

                    I would add a transaction around it and not use prepared statement (since there is nothing to prepare)

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    tovaxT 1 Reply Last reply
                    2
                    • Christian EhrlicherC Christian Ehrlicher

                      I would add a transaction around it and not use prepared statement (since there is nothing to prepare)

                      tovaxT Offline
                      tovaxT Offline
                      tovax
                      wrote on last edited by
                      #50

                      @Christian-Ehrlicher
                      Hi, thank you for your reply.
                      Added transaction statement according to your suggestion.
                      JCDemoDatabase

                      1 Reply Last reply
                      0
                      • A.A.SEZENA Offline
                        A.A.SEZENA Offline
                        A.A.SEZEN
                        wrote on last edited by
                        #51

                        Is the record deleted from the database actually deleted? Or is it hidden? What you see as a gap is perhaps just hidden. Perhaps for this reason, autoincrement is only forward. It might be a good choice to let the database do its job.

                        tovaxT 1 Reply Last reply
                        0
                        • A.A.SEZENA A.A.SEZEN

                          Is the record deleted from the database actually deleted? Or is it hidden? What you see as a gap is perhaps just hidden. Perhaps for this reason, autoincrement is only forward. It might be a good choice to let the database do its job.

                          tovaxT Offline
                          tovaxT Offline
                          tovax
                          wrote on last edited by
                          #52

                          @A-A-SEZEN
                          The record is indeed deleted, the order between the records is achieved by the "UNIQUE RowNumber" column, not "PrimaryKey Autoincrement". The insertion and deletion of records are directly operated on the database, and then read to the TableModel and sorted display in TableView.

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved