Joseph Joseph - 27 days ago 8
C++ Question

Is there any cleaner way to do this? (Prepared SQL queries in Qt C++)

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.

Answer Source

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.