Экранировать % (процент) в QSqlQuery::addBindValue() для LIKE

Я использую базу данных SQLite с Qt. Я привязываю значения к запросу вместо того, чтобы передавать их в строке запроса. Однако я не могу понять, как правильно экранировать% (процент) в самом связанном значении.

Например, как изменить этот код, чтобы он выдавал va%ue1, а не value1?

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
db.open();
QSqlQuery q(db);
q.exec("CREATE TABLE test (field1)");
q.exec("INSERT INTO test VALUES (\"value1\")");
q.exec("INSERT INTO test VALUES (\"va%ue1\")");
q.prepare("SELECT field1 FROM test WHERE field1 LIKE ?");
q.addBindValue("va%%%");
q.exec();
while (q.next()) {
    qDebug() << q.value(0);
}

Прямо сейчас это выводит оба:

QVariant(QString, "value1") 
QVariant(QString, "va%ue1") 

Я также пробовал с q.addBindValue("va\\%%");, но он вообще ничего не выводил.


person sashoalm    schedule 23.03.2015    source источник


Ответы (1)


Сопоставление с образцом LIKE работает на другом уровне, чем привязка параметров.

Чтобы экранировать символы '%' или '_', вы должны использовать предложение ESCAPE:

q.prepare("SELECT field1 FROM test WHERE field1 LIKE ? ESCAPE '@'");
q.addBindValue("va@%%");

Вот функция для экранирования любого связанного значения:

QString sqlEscape(QString boundValue)
{
    boundValue.replace('@', "@@");
    boundValue.replace('_', "@_");
    boundValue.replace('%', "@%");
}
person CL.    schedule 23.03.2015