Правильное связывание параметров для SELECT WHERE .. НРАВИТСЯ с использованием fmdb?
Первый раз пользователь fmdb пытается начать все правильно. У меня есть простая таблица, которую я хочу выполнить запрос SELECT WHERE .. LIKE, и после попытки нескольких документированных подходов, я не могу получить ни один, чтобы дать правильные результаты.
например
// 'filter' is an NSString * containing a fragment of
// text that we want in the 'track' column
NSDictionary *params =
[NSDictionary dictionaryWithObjectsAndKeys:filter, @"filter", nil];
FMResultSet *results =
[db executeQuery:@"SELECT * FROM items WHERE track LIKE '%:filter%' ORDER BY linkNum;"
withParameterDictionary:params];
Или же
results = [db executeQuery:@"SELECT * FROM items WHERE track LIKE '%?%' ORDER BY linkNum;", filter];
Или же
results = [db executeQuery:@"SELECT * FROM items WHERE track LIKE '%?%' ORDER BY linkNum;" withArgumentsInArray:@[filter]];
Я прошел и все методы сходятся в методе fmdb:
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args
В зависимости от подхода и, следовательно, какие параметры равны нулю, он либо вызывает sqlite3_bind_parameter_count(pStmt)
, который всегда возвращает ноль, или, в случае словаря, вызывает sqlite3_bind_parameter_index(..)
, который также возвращает ноль, поэтому параметр не попадает в LIKE, и тогда resultSet из запроса неверен.
Я знаю, что это абсолютно неправильный способ сделать это (SQL-инъекция), но это единственный способ, которым мне удалось удостовериться в моем LIKE:
NSString *queryString = [NSString stringWithFormat:@"SELECT * FROM items WHERE track LIKE '%%%@%%' ORDER BY linkNum;", filter];
results = [db executeQuery:queryString];
(Я также перепробовал все перестановки, но с двойными кавычками вместо одинарных кавычек, показанных здесь)
Обновить:
Я также попробовал собственный вариант fmdb…WithFormat, который должен обеспечить удобство и защиту от инъекций:
[db executeQueryWithFormat:@"SELECT * FROM items WHERE track LIKE '%%%@%%' ORDER BY linkNum;", filter];
Снова, входя в отладчик, я вижу, что LIKE трансформируется из этого:
… LIKE '%%%@%%' ORDER BY linkNum;
К этому:
… LIKE '%%?%' ORDER BY linkNum;
... который также продолжает возвращать ноль от sqlite3_bind_parameter_count()
где я ожидал бы положительного значения, равного "индексу наибольшего (самого правого) параметра". (из документации sqlite)
1 ответ
Ошибка заключалась в том, чтобы включить любые кавычки:
[db executeQuery:@"SELECT * FROM items WHERE track LIKE ? ORDER BY linkNum;", filter];
... и %
сейчас в filter
переменная, а не в запросе.