QSqlQuery绑定值语法问题排查:绑定值后查询无记录返回的原因定位
问题分析与解决
嘿,你遇到的这个问题核心错误其实很明确——你把SQL占位符:machine放在了单引号的内部,还和通配符%写在了一起,这直接导致Qt的SQL预处理机制根本识别不出这个占位符,绑定值自然无法生效。
为什么会出错?
当你写LIKE '%:machine'时,SQL解析器会把整个'%:machine'当成一个固定的字符串字面量,而不是一个包含占位符的匹配表达式。这就意味着query.bindValue(":machine", machine)这条代码找不到对应的占位符可以绑定,所以boundValues()返回空列表,最终查询的是dd_nomdest等于字符串%:machine的记录——显然这不是你想要的结果。
至于拼接字符串能工作,那是因为你直接把machine的真实值硬编码进了SQL里,但这种做法存在严重的SQL注入风险,绝对是不推荐的写法。
两种正确的解决方式
方案1:把通配符加到绑定值里
把%直接附加到要绑定的machine变量上,SQL语句里只保留独立的占位符:
QString sql = QString("SELECT * FROM %1 WHERE dd_nomdest LIKE :machine;").arg(TABLE_NEW_ORDERS); QSqlQuery query(_db); if (!query.prepare(sql)) { qWarning() << ID << "Prepare query failed" << sql; qWarning() << ID << query.lastError(); return false; } // 给machine值前后加上%,实现模糊匹配 query.bindValue(":machine", QString("%%1%").arg(machine)); qDebug() << query.boundValues(); while (query.next()) { // do stuff }
这里要注意:Qt的QString里两个%会被转义成一个%,所以QString("%%1%").arg(machine)最终会生成%你的machine值%这样的字符串。
方案2:用SQL Server的字符串拼接函数
SQL Server支持CONCAT函数,你可以在SQL语句里把通配符和占位符拼接起来,这样占位符始终是独立的:
QString sql = QString("SELECT * FROM %1 WHERE dd_nomdest LIKE CONCAT('%', :machine, '%');").arg(TABLE_NEW_ORDERS); QSqlQuery query(_db); if (!query.prepare(sql)) { qWarning() << ID << "Prepare query failed" << sql; qWarning() << ID << query.lastError(); return false; } query.bindValue(":machine", machine); qDebug() << query.boundValues(); while (query.next()) { // do stuff }
这种方式的优势是模糊匹配的逻辑留在SQL层面,绑定的就是原始的machine值,逻辑更清晰。
验证
修改完成后,你再看query.boundValues()就不会是空列表了,执行查询后query.next()也能正常遍历到符合条件的记录。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

