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

why The message is displayed, QSqlQuery :: value: not positioned on a valid record, when I show the information



  • I have the following problem, in a QListView, to which I fill in information from a DB, when selecting an item I show another type of information, the problem is that I get the message: QSqlQuery :: value: not positioned on a valid record. I tried removing this line of code from my function.

    ui-> lwStations-> setCurrentItem (ui-> lwStations-> item (0), QItemSelectionModel :: Select);
    

    and it happens that the message is no longer displayed, so my question would be how can I do that without getting that error.

    I leave the code below

    QHash<int,QString> MainWindow::selectCodEstacion(int id_referencia)
    {
      QHash<int,QString> dataList;
    
      QSqlQuery qry;
      qry.prepare("SELECT dm.id_estacion,dm.codigo_estacion FROM datos_monitoreo AS dm"
                  " JOIN referencias_monitoreo AS rm"
                  " ON dm.id_estacion=rm.id_estacion"
                  " AND rm.id_referencia=?");
      qry.addBindValue(id_referencia);
      //  qry.addBindValue(fecha);
      if(!qry.exec()){
        _errorMessage=qry.lastError().text();
        _errorCode=qry.lastError().nativeErrorCode();
        return dataList;
      }
      while(qry.next()){
        dataList.insert(qry.value(0).toInt(),qry.value(1).toString());
      }
      return dataList;
    }
    
    void MainWindow::loadDataEstMonitoreo()
    {
      if(ui->cboReferencia->count()==0){
        ui->lwEstaciones->clear();
        return;
      }
      ui->lwEstaciones->clear();
      dataList_2=bLayer.selectCodEstacion(dataTableRef.key(ui->cboReferencia->currentText()));
    
      if(!dataList_2.isEmpty()){
        QStringList l=dataList_2.values();
        QListWidgetItem *item;
        for(int i=0;i<dataList_2.count();++i){
          item=new QListWidgetItem(QIcon(":/img/ui-11-128.png"),l.value(i));
          ui->lwEstaciones->addItem(item);
        }
        ui->lwEstaciones->setCurrentItem(ui->lwEstaciones->item(0),QItemSelectionModel::Select);
    
      }
    }
    

    this is where the message is displayed:

    void MainWindow::on_lwProcedencia_itemSelectionChanged()
        {
          loadDataEstMonitoreo();
        }
    

    5cb3ed87-e5c8-4404-8da3-22e22d67de6e-image.png


  • Lifetime Qt Champion

    Hi,

    Which database backend are you using ?
    I am wondering whether you have the connection that is dropped at some untimely moment.



  • Hi, I'm using PostgreSQL



  • This is my class where I connect to the database

    #ifndef DBCONECTION_H
    #define DBCONECTION_H
    #include <QSqlDatabase>
    #include <QSqlError>
    
    class DbConection
    {
    public:
      DbConection();
      QSqlDatabase getConection();
      QString errorMessage(){return _errorMessage;}
    //  void closeConection();
    
    private:
      QString _errorMessage;
    
    };
    
    #endif // DBCONECTION_H
    
    
    #include "dbconection.h"
    
    QSqlDatabase db=QSqlDatabase::addDatabase("QPSQL");
    DbConection::DbConection(){
    }
    
    QSqlDatabase DbConection::getConection()
    {
      if(!db.isDriverAvailable("QPSQL")){
        _errorMessage=db.lastError().databaseText();
        return db;
      }
      db.setDatabaseName("monitoreo_db");
      db.setHostName("localhost");
      db.setPassword("123456");
      db.setPort(5432);
      db.setUserName("postgres");
      if(!db.open()){
        _errorMessage=db.lastError().databaseText();
        return db;
      }
    
      return db;
    
    }
    


  • @lincoln said in why The message is displayed, QSqlQuery :: value: not positioned on a valid record, when I show the information:

    QSqlDatabase db=QSqlDatabase::addDatabase("QPSQL");

    I don't know whether this has any effect on your problem (possibly not), but you are not supposed to keep a QSqlDatabase variable around. https://doc.qt.io/qt-5/qsqldatabase.html#details

    Warning: It is highly recommended that you do not keep a copy of the QSqlDatabase around as a member of a class, as this will prevent the instance from being correctly cleaned up on shutdown. If you need to access an existing QSqlDatabase, it should be accessed with database(). If you chose to have a QSqlDatabase member variable, this needs to be deleted before the QCoreApplication instance is deleted, otherwise it may lead to undefined behavior.

    Yours is not even a class member, it's a global variable. I think you should change over to the correct pattern and use QSqlDatabase QSqlDatabase::database() to retrieve the database previously added via QSqlDatabase QSqlDatabase::addDatabase().



  • @JonB
    Well I am something new in this of Qt, and the truth is I do not know where to put, QSqlDatabase db = QSqlDatabase :: addDatabase ("QPSQL");
    or how should I make the connection correctly, since I have changed that instruction within my function.

    #include "dbconection.h"
    #include <QSqlDatabase>
    
    DbConection::DbConection(){
    
    }
    
    bool DbConection::getConection()
    {
      QSqlDatabase db=QSqlDatabase::addDatabase("QPSQL");
    //  db.database();
    
      if(!db.isDriverAvailable("QPSQL")){
        _errorMessage=db.lastError().text();
        return false;
      }
      db.setDatabaseName("monitoreo_db");
      db.setHostName("localhost");
      db.setPassword("2311046");
      db.setPort(5432);
      db.setUserName("postgres");
      if(!db.open()){
        _errorMessage=db.lastError().databaseText();
        return false;
      }
    
      return true;
    
    }
    

    and I get this message all the time.

    QSqlDatabasePrivate :: addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    dcfa297f-c8d5-46d1-bcf7-bd786797eeee-image.png

    The only thing that occurred to me was to put it globally, and so I no longer get the duplicate connection message.



  • @lincoln
    To get that error I believe you must be calling QSqlDatabase::addDatabase("QPSQL"); more than once in your code. Either you call it somewhere else as well as in DbConection::getConection(), or you call that method twice?

    Typically you should call it just once, say in your main program, or perhaps in the constructor of your main window. Add the database just once, and open it, or open it when you first want to access it. After that use the static QSqlDatabase QSqlDatabase::database() to fetch the reference to the previously-added database when you need it instead of keeping your own QSqlDatabase db variable in existence. So, for example, your getConection() will only need to go return QSqlDatabase::database() --- optionally preceded by adding/opening it once, depending how/where you implement that.

    As stated in the docs, this is required to allow Qt to properly disconnect from the database when your program exits. I mentioned earlier that you should do this but that I am not saying this will resolve the error you reported. It's at least worth getting this sorted and seeing whether the error persists, then take it from there.

    P.S.
    I now see you raised this question in https://forum.qt.io/topic/127941/why-is-a-duplicate-database-connection-message-displayed and got answers there which you accepted. You didn't reference your new post here, so it's a bit of waste of time for me to type in the answer here when you've already received it elsewhere.... Please cross-reference to a new post if you do that, to save people duplicating their answers, thanks.


  • Lifetime Qt Champion

    @lincoln said in why The message is displayed, QSqlQuery :: value: not positioned on a valid record, when I show the information:

    bool DbConection::getConection()

    Why would getConnection() method add a database each time it is called?! You get exactly what you ask to do: you're adding the same database again and again.
    In one of your other threads it was explained that you should add a database once and then simply get it using https://doc.qt.io/qt-5/qsqldatabase.html#database when needed.



  • @JonB ok, thanks


Log in to reply