QtSql:绑定不会改变使用 SQLite 的查询

Posted

技术标签:

【中文标题】QtSql:绑定不会改变使用 SQLite 的查询【英文标题】:QtSql: binding doesn't change query with SQLite 【发布时间】:2018-06-01 12:26:24 【问题描述】:

我有以下代码应该将值绑定到准备语句:

QSqlQuery query(db);
query.setForwardOnly(true);
query.prepare("SELECT Entry.* FROM Entry WHERE body LIKE ?;");
query.addBindValue(QVariant("%" + name + "%"));
query.exec();
tDebug("%s", query.executedQuery().toUtf8().data());

例如,如果name"thing",则查询应该执行语句SELECT Entry.* FROM Entry WHERE body LIKE "%thing%",但它执行SELECT Entry.* FROM Entry WHERE body LIKE ?,几乎就像忽略了绑定值一样。命名占位符也有同样的问题。

【问题讨论】:

【参考方案1】:

我在一个等效示例上进行了尝试,并适当地测试了“prepare”和“exec”的结果,它们都返回一个布尔值。我测试了这些值在 exec 之后是有界的:

  QList<QVariant> list = query.boundValues().values();
  for (int i = 0; i < list.size(); ++i)
    qDebug() << i << ": " << list.at(i).toString();

我测试了我得到了预期的结果

  while (query.next())
    qDebug()<<"result = "<<query.value(0);

确实,executedQuery 不包含有界值,但 Qt 中的注释对此有些模糊:

"如果在不支持它的 DBMS 上执行带有占位符的准备查询,则模拟此查询的准备。原始查询中的占位符被替换为其绑定值以形成新查询。此函数返回修改后的查询。它主要用于调试目的。"

所以我假设对于 postgresql(我所拥有的)和 SQLite,executedQuery 确实返回带有占位符而不是有界值的原始值。

【讨论】:

我正在寻找更多关于如何使 QtSql 实际绑定值。 我解释文档的方式,仅在不支持占位符的数据库的 latestQuery 或 executedQuery 中可见。 但是,executedQuery 应该仍然返回修改后的查询,对吧? @bb94,这里的想法是名称实际上绑定在支持准备好的语句的数据库引擎中,否则 Qt 通过在驱动程序中绑定名称来模拟它。当绑定发生在数据库中时,Qt无法在绑定后返回executedStatement,它只能在Qt侧发生绑定时这样做(当数据库引擎中不支持准备好的语句时)。这就是为什么the documentation 说只有在使用不支持准备好的语句的数据库引擎时才会返回替换的字符串...

以上是关于QtSql:绑定不会改变使用 SQLite 的查询的主要内容,如果未能解决你的问题,请参考以下文章

QT使用SQLite

QT 创建本地数据库(SQLite数据库)存储数据

android如何绑定sqlite最新版本

如何解决 SQLite 查询的空绑定?

在 Qtsql PyQT4 中添加列名和值作为变量

SQLite 片段函数实现不会在 TextView 中将文本格式化为 HTML