2015-10-13 82 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驱动程序。引擎是一个静态类,它包含程序的所有变量所有实例等。 –