2015-10-13 80 views
6

我終於在C++ Qt中修復了我的MySQL連接。然而,當我嘗試綁定值,我得到以下錯誤:Qt MySQL查詢 - 無法綁定值

QSqlError("2036", "QMYSQL3: Unable to bind value", "Using unsupported buffer type: 1701052421 (parameter: 1)") 

我有這些文件:

Engine.h:

#ifndef ENGINE_H 
#define ENGINE_H 

#include "database/mysql.h" 

class engine 
{ 
private: 
    static mysql* _mysql; 
public: 
    static void initialize(); 
    static void destroy(); 

    static mysql get_mysql(); 
}; 

#endif // ENGINE_H 

Engine.cpp:

#include "engine.h" 
#include "entities/member_controller.h" 
#include <QDebug> 

mysql* engine::_mysql; 

void engine::initialize() 
{ 
    _mysql = new mysql(); 

    member* mem = member_controller::get_member(1); 
    qDebug() << "mem name = " << mem->getFirstName() << " " << mem->getSecondName(); 
    delete mem; 
} 

void engine::destroy() 
{ 
    delete _mysql; 
} 

mysql engine::get_mysql() 
{ 
    return *_mysql; 
} 

mysql.h:

#ifndef MYSQL_H 
#define MYSQL_H 

#include <QtSql> 
#include <QString> 
#include "mysql_result.h" 

class mysql 
{ 
private: 
    QSqlDatabase db; 
public: 
    mysql(); 
    ~mysql(); 
    mysql_result create_result(QString query); 
    QSqlError error(); 

    QSqlQuery query_prepare(QString query1) 
    { 
     QSqlQuery query(this->db); 
     query.prepare(query1); 
//  this->query = query; 
     return query; 
    } 
}; 

#endif // MYSQL_H 

(query_prepare body temp。在頭文件只是爲了測試)

mysql.cpp

#include "mysql.h" 

mysql::mysql() 
{ 
    this->db = QSqlDatabase::addDatabase("QMYSQL", "QMYSQL"); 
    this->db.setHostName("localhost"); 
    this->db.setUserName("root"); 
    this->db.setPassword("Eequi4"); 
    this->db.setDatabaseName("test"); 
    this->db.open(); 
} 

mysql::~mysql() 
{ 
} 

QSqlError mysql::error() 
{ 
    return this->db.lastError(); 
} 

member_controller.h:

#ifndef MEMBER_CONTROLLER_H 
#define MEMBER_CONTROLLER_H 

#include <QString> 
#include "member.h" 

class member_controller 
{ 
public: 
    static member* get_member(unsigned int id); 
    static member* get_member(QString email); 
}; 

#endif // MEMBER_CONTROLLER_H 

member_controller.cpp:

#include "member_controller.h" 
#include "database/mysql_result.h" 

#include "engine.h" 
#include "database/mysql_result.h" 
#include <QtSql/QSqlQuery> 

member* member_controller::get_member(unsigned int id) 
{ 
    QSqlQuery result = engine::get_mysql().query_prepare("SELECT * FROM members WHERE member_id = :mem_id"); 
    result.bindValue(":mem_id", id); 

    if (result.exec() && result.first()) 
    { 
     return new member(id, result.value("first_name").toString(), result.value("second_name").toString(), result.value("screen_name").toString(), result.value("email").toString(), result.value("status").toString()); 
    } 
    else 
    { 
     qDebug() << engine::get_mysql().error() << "\n"; 
     qDebug() << result.lastError() << "\n"; 
    } 

    return new member(0, "", "", "", "", ""); 
} 

我希望這是所有的代碼需要。我嘗試使用questionmark除了:mem_id但沒有運氣。

+1

你試過[重建SQL驅動程序(http://stackoverflow.com/a/23165805/1771479)? – agold

+0

你知道我怎麼能在Windows上做到這一點?如果這是一個菜鳥問題,我很抱歉。如果我構建一個Qt 5.4驅動程序並在5.5中使用它,這有什麼關係嗎? –

+1

請參閱:http://doc.qt.io/qt-5/sql-driver.html#how-to-build-the-qmysql-plugin-on-windows – agold

回答

5

我不是C++或Qt專家,也沒有可能調試您的代碼。

但只是因爲好奇,我已經開始調查您的代碼,發現代碼中的可疑行(注:第二個):

mysql_result result = engine::get_mysql().create_result("SELECT * FROM members WHERE member_id = ?"); 

因爲我不是專家,你沒有提供任何includes我不知道你的engine命名空間是什麼,也不是函數get_mysql()的返回類型,也不是create_result的返回。

所以我做了一些猜測:get_mysql()可能返回QSqlDatabase對象?不是嗎?

但該類型不支持任何create_result方法!所以我卡在那裏。

下一步感謝谷歌我在一週前發現了你的another question。我會請包括在您的文章下一次這樣的重要信息,使人們可以看到像你的類和函數:

mysql_result mysql::create_result(QString query) 
{ 
    return mysql_result(this->db.exec(query)); 
} 

mysql_result::mysql_result(QSqlQuery query) 
{ 
    this->query = query; 
} 

現在我能理解你的代碼是2號線正在嘗試做。

我在這裏看到的可疑物是return mysql_result(this->db.exec(query));。這似乎根據函數名稱,你試圖執行查詢並從mysql服務器得到結果

但根據我在member_controller::get_member中看到的算法,在我看來,您只在準備階段但尚未執行。我發現Qt documentation不夠清晰(並且我不是專家),因爲:在數據庫上執行SQL語句並返回一個QSqlQuery對象。而在技術上,你可以說,你有QSqlQuery結果,你可以期望,這一結果絕對是一樣的,如果你這樣做:

//mysql_result mysql::create_result(QString query) 
QSqlQuery mysql::query_prepare(QString query) 
{ 
    QSqlQuery query(this->db); 
    query.prepare(query); 
    this->query = query; 
    return this->query; 
} 

但恕我直言事實並非如此。在你的情況下它已經被執行,這就是爲什麼你以後不能綁定任何參數。所以我建議你改變你的mysql_result mysql::create_result(QString query)或創建另一個功能QSqlQuery mysql::query_prepare(QString query)這對我來說更有意義。並將您的第一行代碼更改爲:

member* member_controller::get_member(int id) 
{ 
    QSqlQuery query = engine::get_mysql().query_prepare("SELECT * FROM members WHERE member_id = ?"); 
    query.addBindValue(value); 

    if (query.exec() && query.first()) 
... 
... 

最後一點我不明白你爲什麼要重新創建weel?如果你已經擁有的Qt的MySQL類,看起來對我非常好,爲什麼你創建自己的類和方法用一條線來調用Qt的方法,如:

void mysql_result::add_parameter(QVariant value) 
{ 
    this->queryObject.addBindValue(value); 
} 

很抱歉,但恕我直言,這不是很好的主意,幾乎沒有意義。

UPDATE展望更新的代碼,我看到:

result.bindValue(":mem_id", id); 

其中result類型是QSqlQuery所以你要調用本地方法bindValue當根據文件第二個參數是const QVariant & val。所以,我會改變您的通話:

result.bindValue(":mem_id", QVariant(id)); 

QVariant mem_id(id); 
result.bindValue(":mem_id", mem_id); 
+0

**最後一點,我不明白你爲什麼要重新發明weel?如果你已經有Qt的mysql類,這對我來說很好看,爲什麼你用一行來創建你自己的類和方法來調用Qt方法,如:** - 因爲queryObject不是公有的。我喜歡這樣做,除了getQueryObject()。addBindValue。 –

+0

'public'只是OOP術語,它與安全性幾乎沒有任何共同之處。所以我仍然沒有看到任何讓代碼更復雜的理由。 **我喜歡這樣做**確定,那是你的代碼和你的項目,確保你可以做任何你想要的和你喜歡的方式。 – Alex

+0

我的意思是我不想爲QSqlQuery對象獲取一個getter,然後從那裏調用該函數,我認爲這種方式會更好。但作爲意見建議我會嘗試重建MySQL驅動程序。引擎是一個靜態類,它包含程序的所有變量所有實例等。 –