QSqlQuery: получить подготовленную строку оператора перед выполнением

В целях тестирования я пытаюсь получить подготовленную строку оператора из объекта QSqlQuery перед его запуском.

Я проверил lastQuery() и executedQuery() методы, но ни один из них не работает.

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);

Мне нужен способ вернуть строку параметра prepare().


person Antonio Pérez    schedule 08.09.2015    source источник
comment
какое количество boundValues ​​()? doc.qt.io/qt-4.8/qsqlquery.html#boundValues   -  person Gombat    schedule 08.09.2015
comment
Мне нужна полная строка SELECT * FROM Foo;, а не только значения, привязанные к заполнителям.   -  person Antonio Pérez    schedule 08.09.2015
comment
Боюсь, решение состоит в том, чтобы получить связанные значения и заменить вопросительные знаки на связанные значения.   -  person Gombat    schedule 08.09.2015
comment
В этом примере нет связанных значений или вопросительных знаков, но lastQuery возвращает пустую строку. Действительно, утверждение с вопросительными знаками было бы действительным для моего текущего варианта использования, но я не нашел метода, который возвращал бы строку перед запуском exec()   -  person Antonio Pérez    schedule 08.09.2015
comment
И я нет. Я бы сохранил оператор в локальной строке и получил бы связанные значения прямо перед выполнением после их привязки и воссоздал бы оператор, используя замену строки и вопросительного знака. Другого варианта не вижу.   -  person Gombat    schedule 08.09.2015
comment
Зачем он тебе перед казнью? Вы все равно ничего не можете с этим поделать, кроме собственного парсера SQL ...   -  person Kuba hasn't forgotten Monica    schedule 08.09.2015
comment
@KubaOber в моем дизайне один класс отвечает за составление операторов SQL и передает объект QSqlQuery другому, который фактически их выполняет. Я бы хотел, чтобы последний выполнил минимальную проверку запроса перед его выполнением.   -  person Antonio Pérez    schedule 08.09.2015
comment
Что ж, значит, вам нужен парсер SQL, и делать такие подстановки для него не составит труда :)   -  person Kuba hasn't forgotten Monica    schedule 08.09.2015
comment
@KubaOber: да, но мне нужно получить инструкцию из объекта QSqlQuery, чтобы разобрать его, о чем я и спрашиваю, если возможно :)   -  person Antonio Pérez    schedule 08.09.2015
comment
Это возможно, если вы представляете запрос как свою собственную структуру данных. Вы не должны использовать QSqlQuery, пока ваша композиция и проверка не будут выполнены. QSqlQuery на самом деле не очень хорошо спроектирован как инструмент обработки запросов высокого уровня. Это способ отправить запрос на выполнение, и на этом все.   -  person Kuba hasn't forgotten Monica    schedule 08.09.2015
comment
@KubaOber, спасибо, звучит неплохо.   -  person Antonio Pérez    schedule 08.09.2015


Ответы (2)


Взглянув на исходный код Qt, я обнаружил, где заканчивается строка в методе prepare:

...
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);

В котором sqlResult является частным QSqlQueryPrivate объектом. Поэтому я бы сказал, что получить строку оттуда может быть сложно.

Однако мне приходит в голову решение. Подкласс QSqlQuery, устанавливающий атрибут QString, который будет содержать подготовленный оператор. Затем переопределите QSqlQuery::prepare(), чтобы он сохранил значение в атрибуте, а затем выполните исходную работу:

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

Затем создайте getPreparedQuery метод для получения значения в любой момент времени.

Я не думаю, что это «чистое» решение, но, тем не менее, оно может вам помочь.

person martinarroyo    schedule 08.09.2015
comment
Разве вы не можете просто изменить частное на защищенное / общедоступное в заголовке? - person fassl; 09.09.2015

q.executedQuery();

Вернет подготовленный запрос.

person Alexander Sorokin    schedule 08.09.2015
comment
OP сказал, что executedQuery не работает в его случае, потому что ему нужна строка запроса перед выполнением. - person SirDarius; 08.09.2015