QSqlQuery::prepare + MySQL ODBC Connector

Я использовал драйвер Qt MySQL с 32-битным MinGW Qt. Это работало:

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 Connector. Я настроил его и изменил код, чтобы отразить это:

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

Это все, что я сделал. Операторы SELECT без предложения WHERE работают должным образом, и я могу манипулировать базой данных через QSqlTableModel, как и раньше.

Просто привязка перестала работать... Я имею в виду, что связанное значение есть, и qDebug возвращает это:

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

но теперь запрос не возвращает строк после exec; но тоже без ошибок... это тоже работает:

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

Любая помощь?


person smsware    schedule 21.11.2018    source источник
comment
Я не знаком с QODBC, но читали ли вы doc.qt. io/qt-5/sql-driver.html#qodbc?   -  person TrebledJ    schedule 22.11.2018
comment
@TrebuchetMS вы имеете в виду что-то конкретное? Я не вижу там никакой полезной информации... ;c   -  person smsware    schedule 22.11.2018
comment
Ммм... возможно, просто опечатка в вопросе, но: QMap((":vid", QVariant(int, 1))) читается как :vip вместо :pid, как в первом фрагменте кода... это правильно?   -  person cbuchart    schedule 26.11.2018
comment
@cbuchart да, просто опечатка, это сокращение от parent_id, и в моем приложении родитель называется местом проведения, поэтому место проведения_id — это видео, вот и все. Это не проблема, приложение работает, если оно связано с драйвером QMySQL.   -  person smsware    schedule 26.11.2018
comment
С комплектом MSVC/64 Qt, использующим 64-битный драйвер MySQL ODBC, заполнители named и positional работают нормально.   -  person Mohammad Kanan    schedule 26.11.2018
comment
@smsware Вы пытались использовать QODBC3 вместо QODBC? Или вы можете попробовать это: q.bindValue(":pid", QVariant(1));   -  person someoneinthebox    schedule 26.11.2018


Ответы (3)


В MySQL 5 представлена ​​поддержка хранимых процедур на уровне 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
   }
   }}
person EngTiyeb    schedule 01.12.2018

У меня всегда работают безымянные параметры в 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.

person Serhiy Kulish    schedule 21.11.2018
comment
он изменил вывод boundValues() на QMap((:a, QVariant(int, 1))), но он все еще не работает... Я вижу, что он был подготовлен и выполнен в общем журнале моего сервера, но я не получил строки на стороне моего приложения. На самом деле, использование ?s было первым, что я сделал. ;с - person smsware; 21.11.2018

В последний раз у меня была аналогичная проблема с неработающими подготовленными запросами из-за старого драйвера базы данных.

По сути, какая-то сторонняя программа поместила старый mysql.dll в мой PATH. Когда мое приложение Qt работало, старая DLL загружалась вместо новой. Разницы между старой и новой версией было достаточно, чтобы Qt не смог подготовить запросы.

Поэтому я рекомендую вам проверить, загружает ли ваше программное обеспечение правильные версии библиотек DLL, связанных с базой данных.

Также не все драйверы Qt поддерживают подготовленные запросы, поэтому вам следует проверить, возвращает ли QSqlDriver::hasFeature(QSqlDriver::PreparedQueries) значение true для используемого вами драйвера.

Обратите внимание, что в моем случае QSqlDriver::hasFeature(QSqlDriver::PreparedQueries) вернуло true, потому что ожидаемая версия DLL должна была поддерживать подготовленные запросы.

person Benjamin T    schedule 26.11.2018
comment
hasFeature возвращает true, и все библиотеки DLL (проверенные с помощью ListDLL), используемые приложением, поступают из C:\Qt\5.11.2\msvc2017_64, C:\Windows\System32 и C:\Program Files\MySQL\Connector ODBC 8.0, поэтому он должен быть в порядке... - person smsware; 29.11.2018