QSqlDatabasePrivate::removeDatabase:连接'myConnectionName'仍在使用中,所有查询将停止工作



我有一个文件夹,其中有很多数据库。有时可以将数据库删除或添加到文件夹中。因此,我使用QTimer并读取所有数据库。

这是我的代码:

this->timer = new QTimer(this);
this->timer->setInterval(15000);
connect(this->timer, &QTimer::timeout, this, [=]() {
    QString path = "C:\Users\User\Desktop\DAXI SMS SENDER\SMSSenderAllBASE";
    //QString path = qApp->applicationDirPath() + "\SMSSenderAllBASE";
    QDir recoredDir(path);
    QStringList allFiles = recoredDir.entryList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden  | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
    for (int i = 0; i < allFiles.size(); i++) {
        QString fullPath = path + "\" + allFiles[i];
        QString connectionName = allFiles[i];
        connectionName = connectionName.remove(connectionName.size() - 4, 4);
        QSqlDatabase db = QSqlDatabase::addDatabase("QIBASE", connectionName);
        db.setDatabaseName(fullPath);
        db.setHostName("localhost");
        db.setPort(3050);
        db.setUserName("SYSDBA");
        db.setPassword("masterkey");
        thrdHelperSendSMS *help = new thrdHelperSendSMS(db, this);
        connect(help, &thrdHelperSendSMS::helperFinished, this, [=](QString connectionName){
            QSqlDatabase t_db = QSqlDatabase::database(connectionName);
            t_db.close();
            QSqlDatabase::removeDatabase(connectionName);
            delete help;
        });
        help->run();
    }
});
this->timer->start();

是的,我敢肯定,辅助信号会发生,这一次我将与此基础没有任何联系。

编辑:如果我删除

   thrdHelperSendSMS *help = new thrdHelperSendSMS(db, this);
   connect(help, &thrdHelperSendSMS::helperFinished, this, [=](QString connectionName){
       QSqlDatabase t_db = QSqlDatabase::database(connectionName);
       t_db.close();
       QSqlDatabase::removeDatabase(connectionName);
       delete help;
   });
   help->run();

示例:

for (int i = 0; i < allFiles.size(); i++) {
    QString fullPath = path + "\" + allFiles[i];
    QString connectionName = allFiles[i];
    connectionName = connectionName.remove(connectionName.size() - 4, 4);
    QSqlDatabase db = QSqlDatabase::addDatabase("QIBASE", connectionName);
    db.setDatabaseName(fullPath);
    db.setHostName("localhost");
    db.setPort(3050);
    db.setUserName("SYSDBA");
    db.setPassword("masterkey");
    QSqlDatabase::removeDatabase(connectionName);
}

我有相同的错误。

您不正确使用removeDatabase()。Sqldatabase的对象需要首先出现范围。请参阅文档。

错误使用

QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
QSqlDatabase::removeDatabase("sales"); // will output a warning

正确使用

{
    QSqlDatabase db = QSqlDatabase::database("sales");
    QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
}
// Both "db" and "query" are destroyed because they are out of scope
QSqlDatabase::removeDatabase("sales"); // correct

在第二个示例中,db将脱离范围after },您将不再看到错误消息QSqlDatabasePrivate::removeDatabase: connection 'myConnectionName' is still in use, all queries will cease to work

请仔细阅读文档。数据库内容是明智的,需要仔细检查每一行。

您也缺少db.close(); - 在删除数据库之前关闭数据库是有意义的。

@user3606329的答案是正确的,但我添加了此可能性:

QSqlDatabase db = QSqlDatabase::database("sales");
{
    QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
    //use query
}
db = QSqlDatabase();
QSqlDatabase::removeDatabase("sales");

您可以使用 std::swap迫使其按需迫使其破坏。我基本上使用BOOST_SCOPE_EXIT用于在要在示波器出口上调用功能的情况,包括未预期退出,例如异常。

#include <boost/scope_exit.hpp>
{
    QSqlDatabase db;
    BOOST_SCOPE_EXIT(this_, &db) { // by reference, otherwise it will copy a stack object
        // access object here through the this_ instead of this ...
        if (db.isOpen()) {
            db.close(); // closing if not yet closed before connection remove
        }
        std::swap(db, QSqlDatabase{}); // destruct via swap
        // CAUTION:
        //  From this point you must not call to `QSqlDatabase::database("MYDB", ...)`, otherwise it will return another constructed object!
        //
        QSqlDatabase::removeDatabase("MYDB");
    } BOOST_SCOPE_EXIT_END
    // ui change from here ...
    // accomplish last ui changes before long blocking operation
    qApp->processEvents();
    db = QSqlDatabase::addDatabase("...", "MYDB");
    // database access from here ...
}
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "conn_name");
db.open();
if (db.open())
    {
        qDebug()<<"DataBase is Open";
    }
    else
    {
        qDebug()<<"DataBase is Not Open";
    }
QSqlQueryModel * model = new QSqlQueryModel();
QSqlQuery query(QSqlDatabase::database("conn_name"));
query.exec("SMTHING")
if (query.exec())
{
   while (query.next())
      {
         ui->QTableView->setModel(model);
         model->setHeaderData(2, Qt::Horizontal, QObject::tr("????"));
      }
}
db.close();
QSqlDatabase::removeDatabase("conn_name");

Here is my code

最新更新