QSqlQuery::prepare + MySQL ODBC 连接器

QSqlQuery::prepare + MySQL ODBC Connector

我在 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;");

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

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

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

但现在查询 returns 执行后没有行;但也没有错误......这也有效:

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

有什么帮助吗?

对我来说,总是在 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 进行了测试。

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

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

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

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

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

MySQL5在SQL级别引入了存储过程支持,但没有API控制IN、OUT、INOUT参数。因此,必须使用 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
   }
   }}