有没有更干净的方法来做到这一点? (在 Qt C 中准备 SQL 查询)
我在我正在处理的 Qt 项目中使用 QSqlQuery::prepare() 和 ::addBindValue() 进行查询。有很多重复的代码,虽然我认为这是“正确”的方式,但我想确定一下。也许有人有其他想法?示例:
QSqlQuery newQuery;
newQuery.prepare("INSERT INTO table "
"(foo,bar,baz,"
"herp,derp,biggerp,"
"alpha,beta,gamma,"
"etc) VALUES "
"(?,?,?,"
"?,?,?,"
"?,?,?,"
"?)");
newQuery.addBindValue(this->ui->txtFoo->text());
newQuery.addBindValue(this->ui->txtBar->text());
newQuery.addBindValue(this->ui->txtBaz->text());
newQuery.addBindValue(this->ui->txtHerp->text());
newQuery.addBindValue(this->ui->txtDerp->text());
newQuery.addBindValue(this->ui->txtBiggerp->text());
newQuery.addBindValue(this->ui->txtAlpha->text());
newQuery.addBindValue(this->ui->txtBeta->text());
newQuery.addBindValue(this->ui->txtGamma->itemText(0));
newQuery.addBindValue(this->ui->txtEtc->text());
newQuery.exec();
您可以看到一遍又一遍地出现一堆相同的“newQuery.addBindValue(this->ui->__________”。这是“最佳”方法吗?
另外,我在 #qt 中问过那天晚上 freenode 但没有得到明确的答案;上面的 (::prepare with ::addBindValue) 是否可以防止 SQL 注入?
I'm using QSqlQuery::prepare() and ::addBindValue() for my queries in a Qt project I'm working on. There's a lot of repeated code and though I think that's the "right" way, I wanted to make sure. Perhaps someone has alternative ideas? Example:
QSqlQuery newQuery;
newQuery.prepare("INSERT INTO table "
"(foo,bar,baz,"
"herp,derp,biggerp,"
"alpha,beta,gamma,"
"etc) VALUES "
"(?,?,?,"
"?,?,?,"
"?,?,?,"
"?)");
newQuery.addBindValue(this->ui->txtFoo->text());
newQuery.addBindValue(this->ui->txtBar->text());
newQuery.addBindValue(this->ui->txtBaz->text());
newQuery.addBindValue(this->ui->txtHerp->text());
newQuery.addBindValue(this->ui->txtDerp->text());
newQuery.addBindValue(this->ui->txtBiggerp->text());
newQuery.addBindValue(this->ui->txtAlpha->text());
newQuery.addBindValue(this->ui->txtBeta->text());
newQuery.addBindValue(this->ui->txtGamma->itemText(0));
newQuery.addBindValue(this->ui->txtEtc->text());
newQuery.exec();
You can see there's a bunch of the same "newQuery.addBindValue(this->ui->__________" over and over. Is this the 'best' way to go about it?
Also, I asked in #qt on freenode the other night but didn't get a definitive answer; will the above (::prepare with ::addBindValue) protect agains SQL injection? The reference didn't really say.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关于 SQL 注入的子问题,
::prepare
和::addBindValue
的组合确实可以完全防止它。这是因为 SQL 引擎永远不会解析绑定值;它们只是编译(准备步骤)之后和执行之前插入的值。当然,从数据库中取出值时也必须小心,但这并不能保护数据库,而是确保这些值不会被用于导致其他恶作剧(例如,注入意外的恶意
In relation to your sub-question on SQL injection, that combination of
::prepare
and::addBindValue
does indeed fully protect against it. This is because the bound values are never parsed by the SQL engine; they're just values that slot in after compilation (the preparation step) and before execution.Of course, you have to be careful when taking values out of the DB too, but that's not protecting the database but rather ensuring that the values aren't used to cause other mischief (e.g., injecting unexpected malicious
<script>
tags into HTML or, worse still, a<blink>
or<marquee>
monstrosity). But that's another problem, and doesn't apply to all uses anyway; putting the values in a strictly plain text GUI field is usually no problem.如果您首先使用绑定创建
QMap
或QStringList
,然后迭代该数据结构并调用addBindValue()
,它可能看起来会更整洁一些对于列表/地图中的每个项目。It might look a bit tidier if you first create a
QMap
orQStringList
with the bindings, then iterate through that data structure and calladdBindValue()
for each item in the list/map.