如何将Qt项目中的MySQL查询与断言为高效?
摘要:个人Qt项目总结——数据库查询断言问题 问题: 当我使用MySQL数据库的查询操作时, 如果查询的数据在数据库中不存在,那么Qt会直接被干崩溃 但是?为什么呢?不应该是返回if语句中的结果吗,为什么会崩溃呢? bug代码示例查询数据
个人Qt项目总结——数据库查询断言问题
问题:
当我使用MySQL数据库的查询操作时,
如果查询的数据在数据库中不存在,那么Qt会直接被干崩溃
但是?为什么呢?不应该是返回if语句中的结果吗,为什么会崩溃呢?
bug代码示例
===========================================================================================
// 查询数据库获取哈希密码和盐
QSqlQuery query(p->db);
query.prepare("SELECT passwd, salt FROM musicplayer WHERE username = :username");
query.bindValue(":username", username);
if (!query.exec() || !query.next())
{
qDebug() << "查询失败或用户名不存在:" << p->db.lastError();
QMessageBox::warning(this, "警告", "用户名或密码错误!");
return;
}
===========================================================================================
为此,我特意写了一个函数用来测试这个问题
但是,在此之前,先来回顾几个知识点
1.query.exec()
query.exec() 用于执行 SQL 查询语句,返回值代表查询是否成功
如果查询执行成功,返回true
如果执行失败(例如表不存在、语法错误等),query.exec() 会返回 false
2.query.next()
query.next() 用于获取查询结果的下一条数据,返回值代表下一行数据是否存在
如果查询执行成功,返回true
如果查询为空(没有任何匹配结果),query.next() 会返回 false
3.与运算符||
执行顺序是从左至右的
现在再来看看测试函数
// 断言bug测试
// 假设数据库已经连接
void Widget::AssertTest()
{
QSqlQuery query(db);
#if 1
// 1.使用断言查询一个不存在的人(给Qt干崩溃了) —— 预处理语句
// 查询结果为空时, query.next() 返回 false
// 但是没有进一步操作无效数据,程序就跳转到错误处理部分
// 然后,嘭!你的QT崩溃了,开始今天晚上的修bug之旅吧
QString username = "111";
query.prepare("select passwd, salt from musicplayer where username = :username");
query.bindValue(":username", username);
#else
// 2.不使用断言查询一个不存在的人(Qt没有崩溃) —— 拼接字符串
// 查询结果为空时, query.next() 返回 false
// 但是没有进一步操作无效数据,程序就跳转到错误处理部分
// 会继续if条件分支,执行错误处理并退出
// 没有进一步访问无效数据或发生未定义行为
query.prepare("select passwd, salt from musicplayer where username = qwwq");
#endif
// 使用断言时,如果查询数据在数据库中不存在(exec执行),那么Qt就会崩溃
// 但是如果将query.exec()和query.next()的执行顺序对调
// 先执行query.next()再执行query.exec()呢
// 如果这样做了,请尽量不要在你老师面前提及到这件事(会被揍的)........
// 当然,如果有仇的话,出门的时候可以多报一下你老师的名字.......
// || 的运算顺序是从左至右
// 1.if (!query.exec() || !query.next())
// 先执
