QSqlQuery 绑定值与 BindValues 与 QString.arg() 是否存在性能差异

QSqlQuery binding values with BindValues vs QString.arg() is there a performance difference?

本文关键字:存在 是否 性能 arg 绑定 BindValues QString QSqlQuery      更新时间:2023-10-16

BindValueQString.arg()数据库之间有区别吗?

QString().arg()

QSqlQuery qry;
qry.prepare(QString("INSERT INTO employee (id, name, salary) VALUES (%1, 'Thad Beaumont', %2)").arg(1001).arg(65000));
qry.exec();

QSqlQuery::bindValue

QSqlQuery query;
query.prepare("INSERT INTO employee (id, name, salary) VALUES (:id, :name,:salary)");
query.bindValue(":id", 1001);
query.bindValue(":name", "Thad Beaumont");
query.bindValue(":salary", 65000);
query.exec();

它们之间有什么性能差异吗?BindValues优于其他方法吗?

根据维基百科,使用预准备语句有两个优点,即性能和抵御SQL注入攻击的弹性

有很多帖子详细解释了有关特定SQL引擎(MySQL,PostgreSQL(的事情,并且由于您的问题被标记为SQLite,因此有一个关于预准备语句在SQLite中性能的详细SO问题。所有这些帖子似乎都同意,准备好的语句比手动执行语句更有效(除了它们的安全优势(。

除了数据库更高效之外,您的代码也更有效。也就是说,在使用预准备语句时,您不必为替换查询字符串中的值的字符串操作付费,而是将所有字符串按原样传输到数据库而不连接,数据库负责执行它们。

我认为你和你的同事把准备好的陈述弄错了。例如,使用它们最著名的目的之一是(尝试(避免SQL注入,这就是为什么无论性能问题如何,都应该始终使用参数并绑定它们。在这种情况下,使用 arg 是没有意义的:它不是参数绑定的替代品,您只是在构建一个 SQL 字符串。如果您 100% 确定参数被很好地过滤/转义/检查,并且使用 exec 执行它,则可以使用它,没有理由使用预准备语句。

QSqlQuery::bindValue()更好。

由于QString不记录%x的位置,

QString("INSERT INTO employee (id, name, salary) VALUES (%1, 'Thad Beaumont', %2)").arg(1001).arg(65000)

,它必须计算每次调用时将参数放在哪里。

另一方面,当调用QSqlQuery::prepare()时,它会记录位置

此外,QSqlQuery::bindValue()对我来说很好,我不再担心'了。

query.bindValue(":name", "Thad's Beaumont")

现在,您可以安全地存储带有 ' 的名称。(在此之前,我有时会用''替换它,有时为了性能,我会用一些很少使用的角色替换它,例如0x000c(。