views:

58

answers:

2

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.

+1  A: 

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.

Donal Fellows
BTW, I don't know Qt at all – I took notice because of the `sqlite` tag – so I can't say if there's a neater way to do the actual binding. A C programmer might use a locally-defined macro for this, but many C++ programmers frown on that sort of usage, so I don't really know.
Donal Fellows
A: 

It might look a bit tidier if you first create a QMap or QStringList with the bindings, then iterate through that data structure and call addBindValue() for each item in the list/map.

teukkam