Search code examples
c++qtqt5qtsql

QtSql: binding doesn't change query with SQLite


I have the following code that's supposed to bind a value to a prepare statement:

QSqlQuery query(db);
query.setForwardOnly(true);
query.prepare("SELECT Entry.* FROM Entry WHERE body LIKE ?;");
query.addBindValue(QVariant("%" + name + "%"));
query.exec();
tDebug("%s", query.executedQuery().toUtf8().data());

For instance, if name was "thing", then the query should execute the statement SELECT Entry.* FROM Entry WHERE body LIKE "%thing%", but it executes SELECT Entry.* FROM Entry WHERE body LIKE ?, almost as if the bound value was ignored. Named placeholders have the same problem.


Solution

  • I tried this on an equivalent example and appropriately testing the result of "prepare" and "exec", which both return a Boolean. I tested that the values are bounded ok after exec with:

      QList<QVariant> list = query.boundValues().values();
      for (int i = 0; i < list.size(); ++i)
        qDebug() << i << ": " << list.at(i).toString();
    

    I tested that I got the expected result with

      while (query.next())
        qDebug()<<"result = "<<query.value(0);
    

    Indeed, the executedQuery did not contain the bounded values, but the comment in Qt is somewhat vague on this:

    "If a prepared query with placeholders is executed on a DBMS that does not support it, the preparation of this query is emulated.The placeholders in the original query are replaced with their bound values to form a new query. This function returns the modified query. It is mostly useful for debugging purposes."

    So I assume that for postgresql (what I have) and SQLite, the executedQuery does return the original with placeholders and not bounded values.