Escape % (процентов) в 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\\%%");, но он ничего не выводил вообще.

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('%', "@%");
}
Другие вопросы по тегам