3

For testing purposes, I'm trying to get the prepared statement string out of a QSqlQuery object before actually running it.

I have checked lastQuery() and executedQuery() methods, but none of them work.

void foo(QSqlQuery& q)
{
    QString statement = q.lastQuery();
    // statement is empty unless exec() is called
}

QSqlQuery q(myDb);
q.prepare("SELECT * FROM Foo;");
foo(q);

I'd like a way to get back the prepare() parameter string.

Antonio Pérez
  • 6,702
  • 4
  • 36
  • 61
  • what abount "boundValues()"? http://doc.qt.io/qt-4.8/qsqlquery.html#boundValues – Gombat Sep 08 '15 at 11:17
  • I want the full string `SELECT * FROM Foo;` not just the values bound to placeholders. – Antonio Pérez Sep 08 '15 at 11:22
  • I'm afraid the solution is to obtain the bound values and replace question marks with the bound values. – Gombat Sep 08 '15 at 11:44
  • The example has no bound values or question marks, still `lastQuery` returns an empty string. Indeed, the statement with question marks would be valid for my current use case, but I found no method that returns the string **before** running `exec()` – Antonio Pérez Sep 08 '15 at 12:05
  • Me neither. I would store the statement in a local string and obtain the boundvalues right before the executation after binding them and recreate the statement by using the string and question mark replacement. I don't see another option. – Gombat Sep 08 '15 at 12:11
  • Why do you need it before execution? You can't do anything with it anyway, short of having your own SQL parser... – Kuba hasn't forgotten Monica Sep 08 '15 at 12:40
  • @KubaOber in my design, one class is responsible for composing the SQL statements and pass a QSqlQuery object to another that actually executes them. I'd like the latter to perform some minimal validation on the query before actually executing it. – Antonio Pérez Sep 08 '15 at 12:45
  • Well, so you need an SQL parser then, and doing such substitutions will be not a problem for it :) – Kuba hasn't forgotten Monica Sep 08 '15 at 12:47
  • @KubaOber yes, but I do need to get the statement out of the `QSqlQuery` object in order to parse it, which is what I'm asking if possible :) – Antonio Pérez Sep 08 '15 at 13:00
  • 2
    It's possible as long as you represent the query as your own data structure. You shouldn't be using `QSqlQuery` until your composition and validation is done. `QSqlQuery` is not really designed well to be a high-level query manipulation tool. It's a way to submit a query for execution, and that's about it. – Kuba hasn't forgotten Monica Sep 08 '15 at 13:15
  • @KubaOber thanks, that sounds good. – Antonio Pérez Sep 08 '15 at 13:17

2 Answers2

4

Having a look at the Qt source code, I found where the string ends up in the prepare method:

...
if (query.isEmpty()) {
    qWarning("QSqlQuery::prepare: empty query");
    return false;
}
#ifdef QT_DEBUG_SQL
    qDebug("\n QSqlQuery::prepare: %s",query.toLocal8Bit().constData());
#endif
return d->sqlResult->savePrepare(query);

In which sqlResult is a private QSqlQueryPrivate object. So I would say it might be complicated to get the string from there.

However, a solution comes to my mind. Subclass QSqlQuery, setting a QString attribute which will hold the prepared statement. Then redefine the QSqlQuery::prepare() so it stores the value in the attribute, and then does the original job:

bool TestQSqlQuery::prepare(const QString& query){
    this->m_preparedQuery = query;
    return QSqlQuery::prepare(query);
}

Then create a getPreparedQuery method to retrieve the value at any given time.

I don't think it is a 'clean' solution, but it might help you nonetheless.

martinarroyo
  • 9,389
  • 3
  • 38
  • 75
-1
q.executedQuery();

Will return prepared query.

  • OP said that `executedQuery` does not work in his case, because he needs the query string **before** execution. – SirDarius Sep 08 '15 at 11:33