简体   繁体   English

QSqlQuery :: prepare + MySQL ODBC连接器

[英]QSqlQuery::prepare + MySQL ODBC Connector

I was using Qt's MySQL driver with 32bit MinGW Qt. 我在32位MinGW Qt上使用Qt的MySQL驱动程序。 This was working: 这正在工作:

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
}   }   }

But now that I'm using 64bit MSVS Qt, I need to use MySQL ODBC Connector. 但是,既然我使用的是64位MSVS Qt,则需要使用MySQL ODBC Connector。 I've set it up and changed the code to reflect that: 我已经设置并更改了代码以反映这一点:

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

That's all I did. 这就是我所做的。 SELECT statements without WHERE clause are working as expected and I can manipulate the database via QSqlTableModel like before. 不带WHERE子句的SELECT语句按预期工作,我可以像以前一样通过QSqlTableModel操作数据库。

It's just that the binding stopped working... I mean the bound value is there and qDebug returns that: 只是绑定停止工作...我的意思是绑定值在那里,qDebug返回:

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

but now the query returns no rows after the exec; 但是现在查询在exec之后不返回任何行; but also no errors... this also works: 但也没有错误...这也可以:

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

Any help? 有什么帮助吗?

For me always works unnamed parameters in QSqlQuery . 对我来说,总是在QSqlQuery未命名的参数。 For example: 例如:

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

Tested with MySql (Linux), ODBC (mingw), QSqlite. 经过MySql(Linux),ODBC(mingw)和QSqlite的测试。

The last time I had a similar issue of prepared queries not working, it was because of an old database driver. 我上次遇到类似的问题,即准备好的查询无法正常工作,这是因为数据库驱动程序过旧。

Basically some 3rd-party program put an old mysql.dll in my PATH. 基本上,一些第三方程序在我的PATH中放置了一个旧的mysql.dll When my Qt application was running the old DLL was loaded instead of the newer one. 当我的Qt应用程序运行时,将加载旧的DLL,而不是较新的DLL。 The difference between the old and the new version was enough to make Qt fail to prepare queries. 新旧版本之间的差异足以使Qt无法准备查询。

So I recommend you check your software is loading the correct versions of your database related DLLs. 因此,我建议您检查软件是否正在加载与数据库相关的DLL的正确版本。

Also not all Qt drivers support prepared queries, so you should check if QSqlDriver::hasFeature(QSqlDriver::PreparedQueries) returns true for the driver you use. 同样,并非所有Qt驱动程序都支持QSqlDriver::hasFeature(QSqlDriver::PreparedQueries)准备的查询,因此您应该检查QSqlDriver::hasFeature(QSqlDriver::PreparedQueries)是否为您使用的驱动程序返回true。

Note that in my case QSqlDriver::hasFeature(QSqlDriver::PreparedQueries) did return true, because the expected version of the DLL was supposed to support prepared queries. 请注意,在我的情况下, QSqlDriver::hasFeature(QSqlDriver::PreparedQueries)确实返回了true,因为DLL的预期版本应该支持准备好的查询。

MySQL 5 introduces stored procedure support at the SQL level, but no API to control IN, OUT, and INOUT parameters. MySQL 5在SQL级别引入了存储过程支持,但没有用于控制IN,OUT和INOUT参数的API。 Therefore, parameters have to be set and read using SQL commands instead of QSqlQuery::bindValue(). 因此,必须使用SQL命令而不是QSqlQuery :: bindValue()来设置和读取参数。

Try to avoid binding http://doc.qt.io/qt-5/sql-driver.html , use procedures or add your params dynamically: 尝试避免绑定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
   }
   }}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM