Using QSqlQuery::bindValue() for variable number of placeholders I am familiar with the simple use of QSqlQuery::prepare() and QSqlQuery::bindValue() as in:

QSqlQuery query;
query.prepare("SELECT name, address FROM members WHERE id = :id");
query.bindValue(":id", member_id);
query.exec();


In this scenario I show a list of people (members) to the user, all with a check-box in front. The user can simply check which members to delete.
So now, the number of :id are variable.

Currently, I solve this issue in quite a untidy fashion. All the id's checked people will be put in an array of integers called checked_items_ids and then I simply for-loop that array:

QString prepare_query = QString("DELETE FROM members WHERE id = ").append(checked_items_ids[0]);

for(int i = 1; i &lt; checked_items_ids.count(); i++)
    prepare_query.append(QString(" OR id = %1").arg(checked_items_ids[i]));

QSqlQuery query(prepare_query);
query.exec();


Is there a 'tidier' way to do this? Using bindValue() or anything that I might be overlooking?
I'm not the expert for QSqlQuery, so my answer might be slightly off the mark. I see nothing wrong in not using prepare() and bindValue(). It also seems to me a bit "odd" to use these in a DELETE statement. As I said, I'm not the expert on this, there may be other guys that can shed some light on this aspect.

I see two cosmetic issues: 


the way you use checked_items_ids, first time with null argument, second time iterating. A QStringList can help in constructing the SQL statement.
setting the SQL statement in the constructor. Setting it in the exec() function might be more "natural".


These are cosmetic issues only. They do, however, improve readability of your code.

QStringList querylist;
for(auto id : checked_items_ids)
    querylist &lt;&lt; QString("id = %1").arg(id);
QString querystring = QString("DELETE FROM members WHERE ") +
                  querylist.join(" OR ");

QSqlQuery query;
query.exec(querystring);