Qt中如何通过QSqlQuery将SQL查询结果赋值给变量?
正确实现Qt中通过QSqlQuery从数据库获取字段值并赋值给变量
你的代码主要有两个核心问题:一是把QSqlQuery::prepare()的返回值(布尔值,仅表示查询语句是否准备成功)直接赋值给变量,完全搞错了数据来源;二是多次调用prepare()会覆盖之前的查询语句,最后只有最后一条SQL会被执行,前面的查询都白做了。
下面是修正后的完整实现,我会一步步解释关键点:
void Registration::introductionDate(QString email){ // 用栈对象创建QSqlQuery,无需手动delete,避免内存泄漏 QSqlQuery query; // 一次查询所有需要的字段,减少数据库交互次数,提升效率 QString sql = "SELECT dailyCalorieIntake, dailyProteinIntake, dailyIntakeOfCarbohydrates, dailyIntakeOfFats, bmi FROM [dbo].[User] WHERE email = :email"; // 先检查查询语句是否准备成功 if (!query.prepare(sql)) { QMessageBox::critical(this, "初始化错误", query.lastError().text()); return; } // 绑定参数,防止SQL注入 query.bindValue(":email", email); // 执行查询并检查是否成功 if (!query.exec()) { QMessageBox::critical(this, "查询错误", query.lastError().text()); return; } // 初始化变量为默认值,避免未查询到数据时出现垃圾值 int dailyCalorieIntake = 0; int dailyProteinIntake = 0; int dailyIntakeOfCarbohydrates = 0; int dailyIntakeOfFats = 0; float bmi = 0.0f; // 移动到查询结果的第一条记录(因为邮箱应该是唯一的,所以最多一条结果) if (query.next()) { // 从结果集中提取对应字段的值 // 方式1:通过字段索引(顺序和SELECT语句中的字段顺序一致) dailyCalorieIntake = query.value(0).toInt(); dailyProteinIntake = query.value(1).toInt(); dailyIntakeOfCarbohydrates = query.value(2).toInt(); dailyIntakeOfFats = query.value(3).toInt(); bmi = query.value(4).toFloat(); // 方式2:通过字段名(更直观,即使SELECT字段顺序变化也不会出错) // dailyCalorieIntake = query.value("dailyCalorieIntake").toInt(); // dailyProteinIntake = query.value("dailyProteinIntake").toInt(); // dailyIntakeOfCarbohydrates = query.value("dailyIntakeOfCarbohydrates").toInt(); // dailyIntakeOfFats = query.value("dailyIntakeOfFats").toInt(); // bmi = query.value("bmi").toFloat(); } else { // 未找到对应邮箱的用户,给出提示 QMessageBox::warning(this, "提示", "未找到该邮箱对应的用户"); } // 更新UI控件 days->getUi().proteinsEaten->setText("0/" + QString::number(dailyProteinIntake)); days->getUi().calorieEaten->setText("0/" + QString::number(dailyCalorieIntake)); days->getUi().carbohydratesEaten->setText("0/" + QString::number(dailyIntakeOfCarbohydrates)); days->getUi().fatsEaten->setText("0/" + QString::number(dailyIntakeOfFats)); // 原代码中BMI的"0/"可能不合理,这里直接显示数值,你可以根据需求调整 days->getUi().bmiValue->setText(QString::number(bmi)); }
关键知识点说明:
QSqlQuery的正确使用流程:prepare()(准备语句)→bindValue()(绑定参数)→exec()(执行查询)→next()(移动到结果行)→value()(提取数据)。prepare()的返回值:它返回的是bool类型,仅用于判断SQL语句是否合法、能否被数据库解析,不是查询结果。- 减少数据库交互:一次性查询所有需要的字段,比多次查询同一个用户的数据效率高得多,也避免了重复代码。
- 结果集读取:执行
exec()后,查询结果集处于初始位置(第一条记录之前),必须调用next()才能移动到第一条记录;如果有多个结果,可以用while(query.next())循环遍历。 - 类型转换:
query.value()返回的是QVariant类型,需要用toInt()、toFloat()等方法转换为你需要的变量类型。 - 内存安全:尽量使用栈上的
QSqlQuery对象,而不是用new创建堆对象,避免忘记delete导致内存泄漏。
内容的提问来源于stack exchange,提问作者Анатолий Чехов
相关产品推荐
相关产品推荐

