我在我正在研究的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-> __________”一遍又一遍。这是“最好的”方式吗?
另外,我在freenode的#qt上问了另一个晚上,但没有得到确定的答案;以上(:: prepare with :: addBindValue)会保护再次SQL注入吗?引用并没有真正说出来。
答案 0 :(得分:4)
如果您首先使用绑定创建QMap
或QStringList
,然后遍历该数据结构并为列表/地图中的每个项目调用addBindValue()
,那么看起来可能会更整洁一些
答案 1 :(得分:3)
关于SQL注入的子问题,::prepare
和::addBindValue
的组合确实可以完全防范它。这是因为SQL引擎从不解析绑定值;它们只是在编译(准备步骤)之后和执行之前插入的值。
当然,在从数据库中取值时也要小心,但这并不是保护数据库,而是确保这些值不会导致其他恶作剧(例如,注入意外的恶意{{1}标记到HTML中,或者更糟糕的是,<script>
或<blink>
怪物。但这是另一个问题,并不适用于所有用途;将值放在严格的纯文本GUI字段中通常没有问题。