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. Detect a database error before executing a query
Forum Updated to NodeBB v4.3 + New Features

Detect a database error before executing a query

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 755 Views 1 Watching
  • 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.
  • M Offline
    M Offline
    Mark81
    wrote on last edited by
    #1

    On Ubuntu 22.04 with Qt 6.4.0 I open a database connection on the local machine:

    Orders::Orders(QObject *parent) : QObject{parent}
    {
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "orders");
        db.setHostName("localhost");
        db.setDatabaseName("database");
        db.setUserName("user");
        db.setPassword("password");
        db.open();
    
        // QSqlTableModel *_model; <-- declared as private member
        _model = new QSqlTableModel(this, db);
        _model->setTable("orders");
        _model->setEditStrategy(QSqlTableModel::OnManualSubmit);
        _model->select();
    }
    

    It happens that after some time (hours... not sure how many exactly) when I execute a query like this:

    void Orders::appendEvent(QString machine, EventType event)
    {
        QSqlDatabase db = QSqlDatabase::database("orders");
        QString sql = QString("INSERT INTO orders (datetime, machine, an_events_id) VALUES (current_timestamp(), :machine, :event);");
        QSqlQuery query(db);
        query.prepare(sql);
        query.bindValue(":machine", machine);
        query.bindValue(":event", static_cast<int>(event));
        query.exec();
        if (query.lastError().type() != QSqlError::NoError) qWarning() << query.lastError();
    }
    

    I get the following error:

    QSqlError("2013", "QMYSQL: Unable to execute query", "Lost connection to MySQL server during query")

    The error message seems misleading to me (I'm not a native English speaker, though). Does it really say the connection was lost during the execution of the query? Or it means that during the execution of the query it detected the connection was lost?

    In any case, I'm trying to catch the disconnection before I need it. Otherwise, if I detect an error during a query execution I need to save the data, put inside a queue and retry later.

    Looking at the docs I don't find any signal (like "disconnected" or "errorChanged"). What is the recommended way? Have I to constantly polling QSqlDatabase::lastError() ? I'm not sure if it can detect an error if I don't execute a query, though...

    Christian EhrlicherC 1 Reply Last reply
    0
    • M Mark81

      On Ubuntu 22.04 with Qt 6.4.0 I open a database connection on the local machine:

      Orders::Orders(QObject *parent) : QObject{parent}
      {
          QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "orders");
          db.setHostName("localhost");
          db.setDatabaseName("database");
          db.setUserName("user");
          db.setPassword("password");
          db.open();
      
          // QSqlTableModel *_model; <-- declared as private member
          _model = new QSqlTableModel(this, db);
          _model->setTable("orders");
          _model->setEditStrategy(QSqlTableModel::OnManualSubmit);
          _model->select();
      }
      

      It happens that after some time (hours... not sure how many exactly) when I execute a query like this:

      void Orders::appendEvent(QString machine, EventType event)
      {
          QSqlDatabase db = QSqlDatabase::database("orders");
          QString sql = QString("INSERT INTO orders (datetime, machine, an_events_id) VALUES (current_timestamp(), :machine, :event);");
          QSqlQuery query(db);
          query.prepare(sql);
          query.bindValue(":machine", machine);
          query.bindValue(":event", static_cast<int>(event));
          query.exec();
          if (query.lastError().type() != QSqlError::NoError) qWarning() << query.lastError();
      }
      

      I get the following error:

      QSqlError("2013", "QMYSQL: Unable to execute query", "Lost connection to MySQL server during query")

      The error message seems misleading to me (I'm not a native English speaker, though). Does it really say the connection was lost during the execution of the query? Or it means that during the execution of the query it detected the connection was lost?

      In any case, I'm trying to catch the disconnection before I need it. Otherwise, if I detect an error during a query execution I need to save the data, put inside a queue and retry later.

      Looking at the docs I don't find any signal (like "disconnected" or "errorChanged"). What is the recommended way? Have I to constantly polling QSqlDatabase::lastError() ? I'm not sure if it can detect an error if I don't execute a query, though...

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Use QSqlDatabase::isOpen() and also look at the mysql option MYSQL_OPT_RECONNECT.

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

      M 1 Reply Last reply
      1
      • Christian EhrlicherC Christian Ehrlicher

        Use QSqlDatabase::isOpen() and also look at the mysql option MYSQL_OPT_RECONNECT.

        M Offline
        M Offline
        Mark81
        wrote on last edited by
        #3

        @Christian-Ehrlicher so this bug is completely resolved? Can I reliably rely on isOpen() then?

        Christian EhrlicherC 1 Reply Last reply
        0
        • M Mark81

          @Christian-Ehrlicher so this bug is completely resolved? Can I reliably rely on isOpen() then?

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Mark81 said in Detect a database error before executing a query:

          Can I reliably rely on isOpen() then?

          You should use also MYSQL_OPT_RECONNECT since we can only do what the client library gives to us: https://dev.mysql.com/doc/c-api/8.0/en/mysql-info.html - no real connection check.
          mysql_ping() will only work with MYSQL_OPT_RECONNECT so no need to add this to isOpen().

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

          M 1 Reply Last reply
          1
          • Christian EhrlicherC Christian Ehrlicher

            @Mark81 said in Detect a database error before executing a query:

            Can I reliably rely on isOpen() then?

            You should use also MYSQL_OPT_RECONNECT since we can only do what the client library gives to us: https://dev.mysql.com/doc/c-api/8.0/en/mysql-info.html - no real connection check.
            mysql_ping() will only work with MYSQL_OPT_RECONNECT so no need to add this to isOpen().

            M Offline
            M Offline
            Mark81
            wrote on last edited by
            #5

            @Christian-Ehrlicher it surely needs more testing, but it seems that adding the MYSQL_OPT_RECONNECT prevented the above error.

            M 1 Reply Last reply
            0
            • M Mark81

              @Christian-Ehrlicher it surely needs more testing, but it seems that adding the MYSQL_OPT_RECONNECT prevented the above error.

              M Offline
              M Offline
              Mark81
              wrote on last edited by Mark81
              #6

              @Christian-Ehrlicher,
              I have to change my assertion. After about 48h it still loses the connection with the database:

              QSqlError("2013", "QMYSQL: Unable to reset statement", "Lost connection to MySQL server during query")

              The function is:

              bool Orders::appendOrder(QString machine, int size, QSqlRecord newOrder)
              {
                  OrderKey key = OdbcSql::getOrderKey(newOrder);
                  int length = newOrder.field("mo_quant").value().toInt();
              
                  _model->setFilter("");
                  QSqlRecord record = _model->record();
                  record.setValue("id", OdbcSql::encodeOrderKey(key));
                  record.setValue("machine", machine);
                  record.setValue("reference", newOrder.value("td_riferim"));
                  record.setValue("product", newOrder.value("mo_codart"));
                  record.setValue("length", length / size);
                  record.setValue("date", QDateTime::currentDateTime());
                  record.setValue("states_id", static_cast<int>(DbOrderStates::Queued));
              
                  for (int i = 0; i < record.count(); i++) record.setGenerated(i, true);
                  bool ret = true;
                  ret &= _model->insertRecord(-1, record);
                  ret &= _model->submitAll();
                  if (!ret) qWarning() << _model->lastError();
                  return ret;
              }
              

              Here how initialize the stuff now:

              QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "orders");
              db.setHostName("localhost");
              db.setDatabaseName("database");
              db.setUserName("user");
              db.setPassword("password");
              db.setConnectOptions("MYSQL_OPT_RECONNECT=TRUE;");
              db.open();
              
              // QSqlTableModel *_model; <-- declared as private member
              _model = new QSqlTableModel(this, db);
              _model->setTable("orders");
              _model->setEditStrategy(QSqlTableModel::OnManualSubmit);
              _model->select();
              

              What does actually mean "Unable to reset statement"?

              Why does the MYSQL_OPT_RECONNECT seem not to reconnect as expected?

              JonBJ 1 Reply Last reply
              0
              • M Mark81

                @Christian-Ehrlicher,
                I have to change my assertion. After about 48h it still loses the connection with the database:

                QSqlError("2013", "QMYSQL: Unable to reset statement", "Lost connection to MySQL server during query")

                The function is:

                bool Orders::appendOrder(QString machine, int size, QSqlRecord newOrder)
                {
                    OrderKey key = OdbcSql::getOrderKey(newOrder);
                    int length = newOrder.field("mo_quant").value().toInt();
                
                    _model->setFilter("");
                    QSqlRecord record = _model->record();
                    record.setValue("id", OdbcSql::encodeOrderKey(key));
                    record.setValue("machine", machine);
                    record.setValue("reference", newOrder.value("td_riferim"));
                    record.setValue("product", newOrder.value("mo_codart"));
                    record.setValue("length", length / size);
                    record.setValue("date", QDateTime::currentDateTime());
                    record.setValue("states_id", static_cast<int>(DbOrderStates::Queued));
                
                    for (int i = 0; i < record.count(); i++) record.setGenerated(i, true);
                    bool ret = true;
                    ret &= _model->insertRecord(-1, record);
                    ret &= _model->submitAll();
                    if (!ret) qWarning() << _model->lastError();
                    return ret;
                }
                

                Here how initialize the stuff now:

                QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "orders");
                db.setHostName("localhost");
                db.setDatabaseName("database");
                db.setUserName("user");
                db.setPassword("password");
                db.setConnectOptions("MYSQL_OPT_RECONNECT=TRUE;");
                db.open();
                
                // QSqlTableModel *_model; <-- declared as private member
                _model = new QSqlTableModel(this, db);
                _model->setTable("orders");
                _model->setEditStrategy(QSqlTableModel::OnManualSubmit);
                _model->select();
                

                What does actually mean "Unable to reset statement"?

                Why does the MYSQL_OPT_RECONNECT seem not to reconnect as expected?

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #7

                @Mark81
                This may not have anything to do with Qt and you need to investigate at the MySQL side? Having said that consider trying as per https://forum.qt.io/topic/107690/lost-connection-to-mysql-server-during-query-qmysql3-unable-to-reset-statement/5.

                M 1 Reply Last reply
                0
                • JonBJ JonB

                  @Mark81
                  This may not have anything to do with Qt and you need to investigate at the MySQL side? Having said that consider trying as per https://forum.qt.io/topic/107690/lost-connection-to-mysql-server-during-query-qmysql3-unable-to-reset-statement/5.

                  M Offline
                  M Offline
                  Mark81
                  wrote on last edited by
                  #8

                  @JonB I saw that thread, but here I'm not using an explicit query. I'm using the QSqlTableModel - not sure if I can change something here (i.e. call QSqlQuery::exec() with a pre-built string instead of using QSqlQuery::prepare()).

                  How to investigate on MySQL side? I checked /var/log/mysql/error.log but there are no entries.

                  How to exclude it does not depend on my Qt code?

                  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