Лучшая функция (на основе исходного кода Qt: http://qt.gitorious.org/qt/qt/blobs/4.7/src/sql/kernel/qsqlresult.cpp#line644).
Эта функция должна обрабатывать почти все случаи: этот код не работает с БД Oracle при использовании привязки имен (это единственная БД, котораявстроенная поддержка привязки имени => executeQuery () не возвращает запрос с «?», а исходный запрос ...)
Чтобы иметь возможность поддерживать встроенную привязку имени базы данных, ключи связанных значений должныбыть отсортирован по длине, а затем перебрать отсортированную карту ...
QString getLastExecutedQuery(const QSqlQuery& query)
{
QString sql = query.executedQuery();
const int nbBindValues = query.boundValues().size();
for(int i = 0, j = 0; j < nbBindValues; ++j)
{
i = sql.indexOf(QLatin1Char('?'), i);
if (i <= 0)
{
break;
}
const QVariant &var = query.boundValue(j);
QSqlField field(QLatin1String(""), var.type());
if (var.isNull())
{
field.clear();
}
else
{
field.setValue(var);
}
QString formatV = query.driver()->formatValue(field);
sql.replace(i, 1, formatV);
i += formatV.length();
}
return sql;
}
Редактировать: Я обнаружил ошибку в предыдущей функции, если внутри строки в кавычках существует «?», «?»заменяется следующим доступным значением. Ошибка уже существует в исходном коде Qt. Эта функция должна решить эту проблему (может быть улучшена, но идея есть)
QString getLastExecutedQuery(const QSqlQuery& query)
{
QString sql = query.executedQuery();
int nbBindValues = query.boundValues().size();
for(int i = 0, j = 0; j < nbBindValues;)
{
int s = sql.indexOf(QLatin1Char('\''), i);
i = sql.indexOf(QLatin1Char('?'), i);
if (i < 1)
{
break;
}
if(s < i && s > 0)
{
i = sql.indexOf(QLatin1Char('\''), s + 1) + 1;
if(i < 2)
{
break;
}
}
else
{
const QVariant &var = query.boundValue(j);
QSqlField field(QLatin1String(""), var.type());
if (var.isNull())
{
field.clear();
}
else
{
field.setValue(var);
}
QString formatV = query.driver()->formatValue(field);
sql.replace(i, 1, formatV);
i += formatV.length();
++j;
}
}
return sql;
}