【问题标题】:Qt MySQL Query - Unable to bind valueQt MySQL 查询 - 无法绑定值
【发布时间】:2015-10-13 14:57:58
【问题描述】:

我终于在 C++ 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. in header file just to test)

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, "", "", "", "", "");
}

我希望这是所有需要的代码。我尝试使用除 :mem_id 之外的问号,但也没有运气。

【问题讨论】:

  • 你试过rebuilding the SQL driver吗?
  • 你知道我如何在 Windows 上做到这一点吗?如果这是一个菜鸟问题,我很抱歉。如果我构建一个 Qt 5.4 驱动程序并在 5.5 中使用它有关系吗?
  • 我试过了,但是 make 不是一个被认可的程序或 w/e,所以我用 make.exe 下载了 GnuWin32,并在 qmake 之后使用它,但没有生成新的 .dll。也许我只是误解了它。使用make,报错:make (e=2): The system cannot find the file specified.

标签: c++ mysql qt


【解决方案1】:

我不是 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 方法!所以我就卡在那里了。

接下来感谢 google,我找到了您一周前创建的 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;
}

现在我可以理解你的代码的第二行试图做什么了。

我在这里看到的可疑之处是return mysql_result(this-&gt;db.exec(query));。这似乎是根据您尝试 执行 查询并从 mysql 服务器获取 result 的函数名称。

但是根据我在您的member_controller::get_member 中看到的算法,在我看来您只是处于prepare 阶段但尚未执行。我看到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())
...
...

最后一点,我不明白你们为什么要重新发明轮毂?如果你已经有 Qt mysql 类,这对我来说看起来非常好,你为什么要创建自己的类和方法,用一行来调用 Qt 方法,例如:

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

对不起,恕我直言,这不是一个好主意,几乎没有意义。

更新查看我看到的更新代码:

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

其中result 类型为QSqlQuery,因此您正在调用本机方法bindValue,其中根据文档的第二个参数为const QVariant &amp; val。所以我会把你的电话改为:

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

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

【讨论】:

  • 最后一点,我不明白你为什么要重新发明轮毂?如果您已经拥有对我来说非常好的 Qt mysql 类,为什么还要用一行来创建自己的类和方法来调用 Qt 方法,例如: - 因为 queryObject 不是公开的。我喜欢这样做,除了 getQueryObject().addBindValue。
  • public 只是 OOP 术语,它与安全几乎没有任何共同之处。所以我仍然看不到任何让代码更复杂的充分理由。 我喜欢这样做好的,那是你的代码和你的项目,确保你可以做任何你想做的事情和你喜欢的方式。
  • 我的意思是我不想要 QSqlQuery 对象的吸气剂,然后从那里调用函数,我认为这样会更好。但正如 cmets 建议的那样,我会尝试重建 mysql 驱动程序。 Engine 是一个静态类,它包含程序的所有变量、所有实例等。
  • 我认为没有理由重建 mysql 驱动程序。测试我的方式只需要 5 分钟。你试过了吗?
  • 对不起,我现在不在家,只是在跟踪 SO。我会在火车上用笔记本电脑或在家时尝试。
猜你喜欢
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 2013-01-17
  • 2015-06-12
相关资源
最近更新 更多