【问题标题】:QSqlQuery::prepare + MySQL ODBC ConnectorQSqlQuery::prepare + MySQL ODBC 连接器
【发布时间】:2018-11-21 19:00:01
【问题描述】:

我正在使用带有 32 位 MinGW Qt 的 Qt 的 MySQL 驱动程序。这是有效的:

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabaseName("MyDatabase");
//SETUP
if (db.open) {
    QSqlQuery q;
    if (q.prepare("SELECT id FROM Things WHERE parent_id = :pid")) {
        q.bindValue(":pid", 1);
        qDebug() << boundValues();
        if (q.exec) {
            //DO STUFF
}   }   }

但现在我使用的是 64 位 MSVS Qt,我需要使用 MySQL ODBC 连接器。我已经设置并更改了代码以反映这一点:

QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName("Driver={MySQL ODBC 8.0 Unicode Driver};DATABASE=MyDatabase;");

这就是我所做的一切。没有 WHERE 子句的 SELECT 语句按预期工作,我可以像以前一样通过 QSqlTableModel 操作数据库。

只是绑定停止工作......我的意思是绑定值在那里并且 qDebug 返回:

QMap((":pid", QVariant(int, 1)))

但是现在查询在 exec 之后没有返回任何行;但也没有错误......这也有效:

q.prepare(QString("SELECT id FROM Things WHERE parent_id = '%1'").arg(1))

有什么帮助吗?

【问题讨论】:

  • 我不熟悉QODBC,但是你读过doc.qt.io/qt-5/sql-driver.html#qodbc吗?
  • @TrebuchetMS 你有什么特别的想法吗?我在那里看不到任何有用的信息... ;c
  • 嗯...可能只是问题中的一个错字,但是:QMap((":vid", QVariant(int, 1))) 读取 :vip 而不是:pid,如第一个代码 sn-p... 正确吗?
  • @cbuchart 是的,只是一个错字,它是“parent_id”的快捷方式,在我的应用程序中,父级被命名为“venue”,所以“venue_id”是“vid”,仅此而已。这不是问题,如果与 QMySQL 驱动程序连接,该应用程序正在运行。
  • 使用 MSVC /64 Qt 套件,使用 MySQL ODBC 64 位驱动程序,namedpositional 占位符都可以正常工作。

标签: mysql qt odbc qsqlquery qsqltablemodel


【解决方案1】:

MySQL 5 在 SQL 级别引入了存储过程支持,但没有用于控制 IN、OUT 和 INOUT 参数的 API。因此,必须使用 SQL 命令而不是 QSqlQuery::bindValue() 来设置和读取参数。

尽量避免绑定http://doc.qt.io/qt-5/sql-driver.html,使用过程或动态添加参数:

  public void mtd(int param)
   {
   if (q.prepare("SELECT id FROM Things WHERE 
        parent_id ='"+param+"'")) {
       if (q.exec) {
        //DO STUFF
   }
   }}

【讨论】:

    【解决方案2】:

    对我来说,QSqlQuery 中的未命名参数始终有效。 例如:

    if (db.open) {
        QSqlQuery q;
        if (q.prepare("SELECT id FROM Things WHERE parent_id = ?")) {
            q.bindValue(0, 1);
            if (q.exec) {
                //DO STUFF
    }   }   }
    

    用 MySql (Linux)、ODBC (mingw)、QSqlite 测试。

    【讨论】:

    • 它将 boundValues() 的输出更改为 QMap((":a", QVariant(int, 1))) 但它仍然不起作用......我可以看到它已经准备好了在我的服务器的一般日志上执行,但我的应用程序端没有行。实际上,使用 ?s 是我做的第一件事。 ;c
    【解决方案3】:

    上次我遇到类似的准备查询不起作用的问题,是因为旧的数据库驱动程序。

    基本上,一些第 3 方程序在我的 PATH 中放置了一个旧的 mysql.dll。当我的 Qt 应用程序运行时,旧的 DLL 被加载而不是新的。新旧版本的差异足以让 Qt 无法准备查询。

    所以我建议您检查您的软件是否加载了与数据库相关的 DLL 的正确版本。

    此外,并非所有 Qt 驱动程序都支持准备好的查询,因此您应该检查 QSqlDriver::hasFeature(QSqlDriver::PreparedQueries) 是否为您使用的驱动程序返回 true。

    请注意,在我的例子中,QSqlDriver::hasFeature(QSqlDriver::PreparedQueries) 确实返回了 true,因为预期的 DLL 版本应该支持准备好的查询。

    【讨论】:

    • hasFeature 返回 true 并且应用程序使用的所有 DLL(使用 ListDLL 检查)来自 C:\Qt\5.11.2\msvc2017_64、C:\Windows\System32 和 C:\Program Files\ MySQL\Connector ODBC 8.0 所以应该没问题...
    猜你喜欢
    • 1970-01-01
    • 2011-06-19
    • 2014-10-15
    • 2019-04-09
    • 1970-01-01
    • 2020-07-06
    • 2012-12-04
    • 2013-03-31
    • 2016-10-17
    相关资源
    最近更新 更多