У меня есть папка, в которой много баз данных. Иногда может быть удалена или добавлена ​​база данных в папку. Поэтому я использую 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();

Да, я уверен, что сигнал helperFinished будет и на этот раз у меня не будет связи с этой базой.

РЕДАКТИРОВАТЬ: Если я удалю

   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);
}

У меня такая же ошибка.

2
Tazo leladze 16 Фев 2018 в 16:33
Это не настоящая ошибка.
 – 
Mohammad Kanan
16 Фев 2018 в 19:39

4 ответа

Лучший ответ

Вы неправильно используете 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(); - Имеет смысл закрыть базу данных перед ее удалением.

10
user3606329 17 Фев 2018 в 00:55
1
Спасибо большое, работает :) Какая проблема могла бы возникнуть, если бы я оставил эту ошибку?
 – 
Tazo leladze
17 Фев 2018 в 09:06
База данных не будет удалена. т.е. когда вы добавляете его снова, он выдает ошибку, которая уже существует.
 – 
user3606329
17 Фев 2018 в 14:57
2
Достаточно было закрыть базу данных, но похоже, что нет. Я думаю, что это проблема Qt.
 – 
Jolly Roger
1 Апр 2019 в 18:07
Роджер, этого недостаточно. Мне также интересно, почему вы комментируете пост, которому больше года?
 – 
user3606329
2 Апр 2019 в 11:52
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
-1
GKS 20 Ноя 2020 в 13:13
db теперь болтается недопустимое соединение с базой данных, ссылка все еще есть QSqlDatabase db
 – 
Albertino80
26 Мар 2021 в 13:53

@ user3606329 ответ правильный, но я добавляю эту возможность:

QSqlDatabase db = QSqlDatabase::database("sales");
{
    QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
    //use query
}
db = QSqlDatabase();
QSqlDatabase::removeDatabase("sales");
0
Albertino80 26 Мар 2021 в 13:56

Вы можете использовать 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 ...
}
0
Andry 2 Мар 2022 в 01:35