【问题标题】:Qt & SqlLite - wrong path to databaseQt & SqlLite - 数据库路径错误
【发布时间】:2017-03-25 08:21:37
【问题描述】:

我实际上正在使用 Qt 和 SqlLite,我的问题是,即使是完全在 sqllite3.exe 上运行的请求也无法在我的程序中运行。我不断收到我设置的错误消息。我想知道这是否真的是代码问题,因为我实际上可以连接到我的数据库,并且在尝试将它们放入 sqllite3.exe 时请求工作正常。

数据库路径:

SQLLITE\musclelayout

DataHandler.cpp - 构造函数(经过许多有用的 cmets 编辑)

DataHandler::DataHandler(QMainWindow* mw, const QString& path)
{
   databaseIsOpen = false;

   database = QSqlDatabase::addDatabase("QSQLITE");
   database.setDatabaseName(path);

   qDebug() << "Opening database:" << path << "from" << QDir::currentPath();
   qDebug() << "Does the file exist:" << QFileInfo::exists(path);

   if(database.open())
   {
       qDebug() << "Database opened. Tables:" << database.tables();
       databaseIsOpen = true;
   }
   else
   {
       QString msgTitle("Cannot login to '" + path + "'");
       QMessageBox::StandardButton alertMsg;
       alertMsg = QMessageBox::warning(mw, msgTitle, database.lastError().text(), QMessageBox::Ok);
   }

}

路径完全错误:

Opening database: "SQLLITEmusclelayout" from "C:/Users/Tong3/Desktop/DEV/build-muscleLayout-Qt_5_8_0_mingw53_32-Debug"
Does the file exist: true
Database opened. Tables: ()

但我无法编写'SQLLITE\'(不会编译),并且路径没有转到我的项目所在的位置。 真实网址:

C:\Users\Tong3\Desktop\DEV\muscleLayout\SQLLITE\musclelayout

DataHandler - getTrainedMucleList()

vector<QString> DataHandler::getTrainedMuscleList(QMainWindow* mw)
{
    vector<QString> tmp_array;

    QSqlQuery query;

    if(databaseIsOpen)
    {
        if(query.exec("SELECT * FROM trainedMuscle"))
        {
            while(query.next())
            {
                tmp_array.push_back(query.value("muscleName").toString());
            }
        }
        else
        {
            QString msgTitle("Cannot load muscle list");
            QMessageBox::StandardButton alertMsg;
            alertMsg = QMessageBox::warning(mw, msgTitle, query.lastError().text(), QMessageBox::Ok);
        }
    }
    else
    {
        QString msgTitle("Cannot login to database");
        QMessageBox::StandardButton alertMsg;
        alertMsg = QMessageBox::warning(mw, msgTitle, database.lastError().text(), QMessageBox::Ok);
    }

    return tmp_array;
}

感谢您花时间阅读我的新手代码, 祝你有美好的一天。

【问题讨论】:

  • 使用query.lastError().text();查看错误信息。
  • 路径是什么?
  • 错误是“找不到受过训练的肌肉”。但表确实存在!路径是“SQLLITE\musclelayout”。数据库打开成功

标签: c++ qt sqlite


【解决方案1】:

关于QSqlQuery

​​>

您没有正确使用 QSqlQuery。

构造函数QSqlQuery(const QString &amp;query = QString(), QSqlDatabase db = QSqlDatabase()) 执行给定的query。引用文档:

使用 SQL 查询和数据库 db 构造一个 QSqlQuery 对象。 如果 db 未指定,或无效,则应用程序的默认值 使用数据库。 如果查询不是空字符串,它将是 执行。

bool QSqlQuery::exec() 用于准备好的查询。仍然引用文档:

执行预先准备好的 SQL 查询。如果查询返回 true 成功执行;否则返回 false。

您可以改用这些示例:

// The most complete form as you could bind values between prepare() and exec()
QSqlQuery query;
query.prepare("SELECT * FROM trainedMuscle");
query.exec();

// A shorter form for when you do not need to bind values
QSqlQuery query;
query.exec("SELECT * FROM trainedMuscle");

// The shortest form, the query is executed in the constructor,
// you do not need to call exec(). Use lastError() to check execution.
QSqlQuery query("SELECT * FROM trainedMuscle");

关于 SQLite

SQLite 也是无服务器的 (https://www.sqlite.org/serverless.html),因此您可以更改打开数据库的方式,因为您不需要设置服务器:

database = QSqlDatabase::addDatabase("QSQLITE");
database.setDatabaseName(path);

if(database.open())
...

另外考虑到您的 cmets,我怀疑您的路径有问题,因此您可以添加一些调试输出以确保您打开了正确的 SQLite 数据库文件:

database = QSqlDatabase::addDatabase("QSQLITE");
database.setDatabaseName(path);

qDebug() << "Opening database:" << path << "from" << QDir::currentPath();
qDebug() << "Does the file exist:" << QFileInfo::exists(path);

if(database.open())
{
    qDebug() << "Database opened. Tables:" << database.tables();
    ....
}

关于在 C++ 中使用反斜杠编写字符串

QString path = "SQLLITE\" 这样的东西不会编译是正常的。反斜杠是一个转义字符,如果你想在一个字符串中放一个反斜杠,你需要加倍它。如果你想写一个 Windows 路径你可以写:

QString path = "C:\\Users\\Tong3\\Desktop\\DEV\\muscleLayout\\SQLLITE\\musclelayout"; // Actually contains "C:\Users\Tong3\Desktop\DEV\muscleLayout\SQLLITE\musclelayout"

但如果您使用 Qt,您可以使用正斜杠作为目录分隔符来编写 Windows 路径,如下所示:

QString path = "C:/Users/Tong3/Desktop/DEV/muscleLayout/SQLLITE/musclelayout";

关于工作目录

之所以“路径不去我的项目所在的地方”,是因为程序的工作目录最初是从程序执行的地方设置的。它既与可执行文件所在的位置无关,也与您的源代码所在的位置无关。

当您在程序中使用相对路径时,它们会相对于该工作目录进行解释。

作为开发人员,您无法控制初始工作目录是什么,因为这取决于用户将如何启动程序。但是,您可以在程序执行期间更改它。

在您的情况下,工作目录是C:/Users/Tong3/Desktop/DEV/build-muscleLayout-Qt_5_8_0_mingw53_32-Debug。此选项可以在 QtCreator 中的“项目”选项卡的“运行设置”中进行更改。

但是我认为最好不要使用相对路径,而是将 SQLite 数据库放在应用程序旁边(请参阅QCoreApplication::apllicationDirPath())或 AppData 文件夹(请参阅QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)),具体取决于用户是否需要写入访问数据库。

【讨论】:

  • 这改变了我收到的query.lastError().text( 的错误消息:no such table trainedMuscle。但该表确实存在。
  • 您可以在打开数据库时使用QSqlDatabase::tables() 列出数据库中的表。这可能只是一个路径问题;您的第一个代码示例中path 的值是多少?如果你用path = "SQLLITE\\musclelayout"之类的东西设置它,首先使用/而不是` even on Windows, Qt takes care of it, secondly you have a relative path and it might end up connecting to the wrong database. You can check the current directory with QDir::currentPath()`。
  • / : 数据库内存不足。 \\ :同样的错误。只有 '\' 有效。看起来我真的连接到数据库。对不起,我不知道如何使用 QSqlDatabase::tables()。它是否在提示符中输入值?
  • @SanchezTanguy 来吧...QSqlDatabase::tables() 是一个函数,记录在 Qt 文档中,它返回一个包含表名的 QStringListdoc.qt.io/qt-5/qsqldatabase.html#tables 如果你想在终端中输出调试信息,请查看QDebug
  • 为什么不能转义'\'?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多