Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QSQlQuery::exec: database not open



  • Hello,

    So I have been receiving this error while running the following code

    void MainWindow::on_serachBox_textEdited(const QString& arg1) {
      // TODO: fix this
      // databse::exec: databse not open
      queryModel.setQuery("SELECT * FROM " + ui->comboBox->currentText() +
                              " WHERE " +
                              handler->getMainField(ui->comboBox->currentText()) +
                              " LIKE \'%" + arg1 + "%\'",
                          handler->getDB());
      qDebug() << queryModel.lastError();
      qDebug() << queryModel.query().lastQuery();
      ui->dataOutput->setModel(&queryModel);
    }
    

    This method runs when the text in line edit changed. I tried doing db->open(); before running thequeryModel.setQuery(...); but got no different result.
    What is really frustrating is when I run the following code, it runs without an issue:

    void MainWindow::updateQuery() {
      handler->open();
      queryModel.setQuery("SELECT * FROM " + ui->comboBox->currentText() +
                          " WHERE 1");
      handler->close();
      ui->dataOutput->setModel(&queryModel);
    }
    

    Can someone explain to me why I am getting this error and how I can fix it?

    Thank you.

    Application output:

    QSqlQuery::exec: database not open
    QSqlError("", "", "")
    "SELECT * FROM test1 WHERE testF_T LIKE '%3%'"
    

    PS.
    The query itself is fine, I checked it



  • @Omar-Alkersh

    Hi and welcome to devnet forum

    There is not need to have a pointer for the db. You can simply open the default as it is shown in the detailed description here. However, you have to open the db prior to access.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    To add to @koahnig, what is that handler object ?



  • @SGaist just a normal object where I keep all my db related methods and object, QSqlQuery, QSqlDatabse etc.I



  • @koahnig I open it at the constructor of the handler object, an object where I keep all the db related methods and vars, to keep things clean


  • Moderators

    @Omar-Alkersh

    the only difference between the 2 code examples you posted is, that in one you pass the database to the queryModel.

    You said you tested it, and it did not work, what exactly is the result when you would change the function to this:

    void MainWindow::on_serachBox_textEdited(const QString& arg1) {
    
    handler->open();
      queryModel.setQuery("SELECT * FROM " + ui->comboBox->currentText() +
                              " WHERE " +
                              handler->getMainField(ui->comboBox->currentText()) +
                              " LIKE \'%" + arg1 + "%\'");
      qDebug() << queryModel.lastError();
      qDebug() << queryModel.query().lastQuery();
      handler->close();
      ui->dataOutput->setModel(&queryModel);
    }
    

    I haven't used the QSqlQueryModel class myself yet, but are you supposed to to piece the query together like this!? Seems wrong.



  • @J.Hilk hello,
    The result is that I get the same meessge, QSqlQuery::exec: database not open, regardless whether I write handler->ope (); or not.
    The QTableView, which I use this model with, would stop displaying any table.

    Basically no difference.


  • Qt Champions 2019

    @Omar-Alkersh Can you show the content of handler->open() ?



  • @jsulm

    
    QSqlDatabase db; //initialised in constructor
    
    void BDHandler::open (){
    db->open ();
    }
    
    handler->close (); //same as open
    

  • Qt Champions 2019

    @Omar-Alkersh said in QSQlQuery::exec: database not open:

    QSqlDatabase db;

    If this is like this in the constructor then it is a local variable in the constructor and not related to the db pointer!
    You also should check the return value of db->open () and print out the output of http://doc.qt.io/qt-4.8/qsqldatabase.html#lastError in case it returns false. Also you did not say how you set up your database.



  • @jsulm

    Thanks for the suggestion but this is a global variable, it is just initialized in the constructor.

    And this is how I set up my db

    DBHandler::DBHandler(MainWindow* mWindow) {
      // init vars
      path = databaseloc.currentPath() + "/database";
      TABLE_MAIN = "main_table";
      COLUMN_ID = "_id";
      COLUMN_MAIN_NAME = "main_name";
    
      // check if dir exits
      QFileInfo fileInfo(path);
      if (!fileInfo.exists()) {
        if (databaseloc.mkpath(path)) {
          mWindow->close();
        }
      }
    
      // db name and loc
      path += "/" + dbName + ".db";
    
      // add db
      db = QSqlDatabase::addDatabase("QSQLITE");
      db.setDatabaseName(path);
    
      // open test, sets up query and creates mainTable if not exists
      if (db.open()) {
        query = QSqlQuery(db);
        query.exec("CREATE TABLE IF NOT EXISTS " + TABLE_MAIN + "(" + COLUMN_ID +
                   " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_MAIN_NAME +
                   " TEXT, mainField TEXT);");
    
      } else {
        // stop programme from continueing
        QMessageBox::StandardButton reply;
    
        reply = QMessageBox::warning(
            mWindow, "Error",
            "Was not able to open database file.\n" + db.lastError().text());
    
        if (reply == QMessageBox::Ok) {
          // exits with error
          exit(1);
        }
      }
      db.close();
    }
    
    


  • @Omar-Alkersh

    Did you notice the close at the end of your constructor?

     }
      db.close();
    }
    

    I guess there is your problem.


  • Lifetime Qt Champion

    Hi,

    To add to @koahnig, why are you opening and closing the database connection again and again ?



  • @SGaist Thank you good sir. It worked. I thought that I should always close the db to stop any memory leaks. I used to develop android and I used to always close it after me.

    Solution was not to close the db. Obviously.


  • Lifetime Qt Champion

    AFAIK, there's no known memory leaks in Qt's SQL drivers.

    Don't get me wrong, there might be good reasons to only open a database connection when needed however this requires a bit more architecture to make it work correctly.


Log in to reply