открыть существующую базу данных sqlite3 под QT - PullRequest
1 голос
/ 19 октября 2011

Я очень плохо знаком с СУБД QT и SQLite. Я пытаюсь открыть существующую базу данных, созданную с помощью программы командной строки "sqlite3" под Ubuntu Linux. Я пытаюсь получить доступ к той же базе данных в QT, используя следующий код:

void MainWindow::func()
{
    QSqlQuery query;
    accounts_db = new QSqlDatabase();
    *accounts_db = QSqlDatabase::addDatabase("QSQLITE");
    perror("? ");
accounts_db->setDatabaseName("/home/user/xyz.db");
QSqlError *a = new QSqlError();
*a = accounts_db->lastError();
perror(a->text().toLatin1());
if (!accounts_db->open()) {
    perror("database open error :");
}
if ( !accounts_db->isOpen() ) {
    perror("database is not open");
}
query.exec("select accno,branchcode,fname,lname,curbalance,accdate from accounts");
while(query.next()) {
    QString str = query.value(0).toString();
    std::cerr << qPrintable(str) << std::endl;
}
end:
;
}

Это происходит со следующими ошибками ...

No such file or directory
: Invalid argument
QSqlQuery::exec: database not open

Обратите внимание, что я получаю «Нет такого файла или каталога» после adddatabase (), не имею понятия, о каком файле идет речь. Также обратите внимание, что isOpen () и open () возвращают «true» (???). Ошибка «база данных не открыта» от вызова db.exec () (... я полагаю ...).

В отчаянной нужде в руководстве ...

Ответы [ 3 ]

5 голосов
/ 19 октября 2011

Конструктор QSqlQuery без параметров использует базу данных по умолчанию для вашего приложения. Возможно это еще не установлено. Используйте конструктор, определяющий базу данных, которую должен использовать запрос:

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "connection_name");
// Open db...
QSqlQuery query(db);
if (!query.exec(...)) {
   // ...
}
// ...

Обратите внимание на то, как впоследствии вы закрываете соединение.

РЕДАКТИРОВАТЬ: Это тест, который я только что написал и работает на моей системе. Вы можете попробовать.

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QVariant>

int main(int argc, char *argv[])
{
    // Create database.
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "Connection");
    db.setDatabaseName("/tmp/test.db");
    if (!db.open()) {
        qDebug("Error occurred opening the database.");
        qDebug("%s.", qPrintable(db.lastError().text()));
        return -1;
    }

    // Insert table.
    QSqlQuery query(db);
    query.prepare("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, text TEXT)");
    if (!query.exec()) {
        qDebug("Error occurred creating table.");
        qDebug("%s.", qPrintable(db.lastError().text()));
        return -1;
    }

    // Insert row.
    query.prepare("INSERT INTO test VALUES (null, ?)");
    query.addBindValue("Some text");
    if (!query.exec()) {
        qDebug("Error occurred inserting.");
        qDebug("%s.", qPrintable(db.lastError().text()));
        return -1;
    }

    // Query.
    query.prepare("SELECT * FROM test");
    if (!query.exec()) {
        qDebug("Error occurred querying.");
        qDebug("%s.", qPrintable(db.lastError().text()));
        return -1;
    }
    while (query.next()) {
        qDebug("id = %d, text = %s.", query.value(0).toInt(),
               qPrintable(query.value(1).toString()));
    }

    return 0;
}
1 голос
/ 19 октября 2011

Это в основном предположение, поскольку ваш код неверен по многим причинам, включая сообщения об ошибках.

Наиболее вероятная проблема заключается в том, что путь к файлу просто неверен, или пользовательзапуск вашего приложения с не имеет соответствующих разрешений на файл и / или каталог.(Примечание: файлы и каталоги чувствительны к регистру в Linux.)

perror следует использовать только после вызова системной функции, которая фактически завершилась ошибкой и которая устанавливает errno, когда это происходит.Qt этого не делает.

Пожалуйста, попробуйте запустить это и обновите ваш вопрос, если вы все еще не можете решить вашу проблему:

void MainWindow::func()
{
    // Note: no pointer!
    QSqlDatabase accounts_db = QSqlDatabase::addDatabase("QSQLITE");
    accounts_db.setDatabaseName("/home/user/xyz.db");
    if (!accounts_db.open())
    {
        qDebug() << "Could not open database file:";
        qDebug() << accounts_db.lastError();
        return;
    }
    // Note: don't construct queries before you have a database!
    QSqlQuery query;
    if (!query.exec("select accno,branchcode,fname,lname,curbalance,accdate from accounts"))   
    {
        qDebug() << "Query failed:";
        qDebug() << query.lastError();
        return;
    }
    while(query.next()) {
      QString str = query.value(0).toString();
      std::cerr << qPrintable(str) << std::endl;
    }
}

(я даже не пытался скомпилировать это,так что, YMMV.)

Посмотрите также примеры SQL и посмотрите, как они там все это обрабатывают.

0 голосов
/ 20 октября 2011

Хорошо, я создал новый файл базы данных с помощью команды sqlite3 , теперь та же самая программа в моем вопросе работает !!!.

Я тоже пробовал это раньше, но тогда это не сработало (... я ненавижу, когда это происходит). Я думаю, предыдущий файл может быть поврежден. Но к предыдущему файлу базы данных можно было получить доступ из программы cmdline sqlite3, поэтому я предполагал, что файл в порядке, но, видимо, нет.

В любом случае, большое спасибо, ребята, что уделили мне время, и очень жаль, что я потратил его впустую :(.

Я отмечаю это как ответ только для ясности, что на этот вопрос дан ответ. Но это не совсем ответ (... потому что я до сих пор не понимаю, что происходит!?)

Еще раз спасибо ...

РЕДАКТИРОВАТЬ:

Вот код

QSqlError *a = new QSqlError();

accounts_db = new QSqlDatabase();
*accounts_db = QSqlDatabase::addDatabase("QSQLITE");

accounts_db->setDatabaseName("/home/user/test.db");

if ( !accounts_db->open() ) {
    qDebug() << accounts_db->lastError();
    qDebug() << "Could not open database file:";
}
QSqlQuery query;

if ( !(accounts_db->isOpen()) ) {
    qDebug() << accounts_db->lastError();
    qDebug() << ": Could not open database file:";
    goto end;   // quit if not successful
}

query.exec("select * from accounts");

while(query.next()) {
    // loop for i columns
    QString str = query.value(i).toString();
    std::cerr << qPrintable(str) << std::endl ;
    // loop
}
end:
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...