3

テーブルがまだ存在しない場合にのみ、sqlite データベースを初期化しようとしています。そうでない場合は、作成する必要があります。これで、チェックは常にクリーンなデータベースで成功します (もちろん、テーブルはまだ存在しません) が、-block 内にテーブルを作成しようとするとif、sqlite は実際に存在すると不平を言います。そのコードの実行後にテーブルが存在することを確認できますが、qFatal呼び出しからまだそのエラー メッセージが表示されます。

#include <QApplication>
#include <QDebug>

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QStringList>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");
    if(!db.open())
        qDebug() << "Couldn't open database file!";
    else
        qDebug() << "Opened database :memory:";

    qDebug() << "Existing tables:";
    QStringList::const_iterator it;
    for(it = db.tables().begin(); it != db.tables().end(); it++)
        qDebug() << it->toLocal8Bit().constData();
    qDebug() << "End";

    if(!db.tables().contains(QString("testtable")))
    {
        // The files table doesn't exist
        qDebug() << "Initializing DB";
        QString queryText = "CREATE TABLE testtable (id varchar(32) NOT NULL)";
        QSqlQuery query(queryText, db);
        if(!query.exec())
            qFatal("Couldn't initialize database: %s: %s", qPrintable(query.lastError().driverText()), qPrintable(query.lastError().databaseText()));
    }

    return a.exec();
}

参照出力:

Opened database :memory: 
Existing tables: 
End 
Initializing DB 
Couldn't initialize database: Unable to fetch row: table testtable already exists

SQLクエリで使用して問題を回避しIF NOT EXISTSましたが、実際には問題は解決しません。(OS X および Ubuntu 12.04 の Qt 4.8)

4

2 に答える 2

0

私は自分でこの動作に気づきました。ソース コードを調べると、次の行が表示されます。

int openMode = (openReadOnlyOption ? SQLITE_OPEN_READONLY : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE));

次に、SQLite のソースに:

** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
** <dd>The database is opened for reading and writing, and is created if
** it does not already exist. This is the behavior that is always used for
** sqlite3_open() and sqlite3_open16().</dd>)^

それ以上はフォローしていませんが、Qt がこのフラグを渡していると想定しても問題ないと思います。

これはドライバー固有の動作のように思われるため、おそらくそれが文書化されていない理由です。

于 2016-01-07T14:02:20.563 に答える