Проблема с FMDB и вставкой значения в "executeQuery:" из searchString - PullRequest
4 голосов
/ 15 июля 2011

При создании поиска для моего приложения я столкнулся с проблемой при использовании FMDB SQLite Wrapper (https://github.com/ccgus/fmdb).

Когда я выполняю поиск в своей базе данных этой командой SQL, все в порядке. Возвращено 13 объектов, и я могу их использовать.

FMResultSet *rs = [db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE '%Daimler%'"];

Но когда я пытаюсь вставить searchQuery из пользовательского ввода, как это:

FMResultSet *rs = [db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE (?)", theSearchQuery];

... значение не может быть вставлено в команду SQL. И я не получаю никаких возвращаемых объектов из БД. даже если строка (theSearchQuery) совпадает с написанной в первом примере.

Кроме того, для вашего удобства я публикую часть документации из FMDB. :)

Data Sanitization

При предоставлении оператора SQL для FMDB не следует пытаться «очистить» какие-либо значения перед вставкой. Вместо этого вы должны использовать стандартный синтаксис привязки SQLite:

ВСТАВИТЬ В myTable VALUES (?,?,?) ? SQLite распознает символ как заполнитель для вставляемого значения. Все методы выполнения принимают переменное число аргументов (или представление этих аргументов, таких как NSArray или va_list), которые должным образом экранированы для вас.

Таким образом, вы НЕ ДОЛЖНЫ делать это (или что-то подобное):

[db executeUpdate: [NSString stringWithFormat: @ "INSERT INTO myTable VALUES (% @)", @ "здесь много \" причудливых \ "кавычек"]]; Вместо этого вы ДОЛЖНЫ сделать:

[db executeUpdate: @ "INSERT INTO myTable VALUES (?)", @ "Здесь много \" причудливых \ "кавычек"]; Все аргументы, предоставленные методу -executeUpdate: (или любому из вариантов, которые принимают va_list в качестве параметра), должны быть объектами. Следующее не будет работать (и приведет к сбою):

[db executeUpdate: @ "INSERT INTO myTable VALUES (?)", 42]; Правильный способ вставить число - это поместить его в объект NSNumber:

[db executeUpdate: @ "INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt: 42]]; В качестве альтернативы вы можете использовать вариант -execute * WithFormat: для использования подстановки в стиле NSString:

[db executeUpdateWithFormat: @ "ВСТАВИТЬ В ЗНАЧЕНИЯ myTable (% d)", 42]; Внутренне, методы -execute * WithFormat: правильно упаковывают вещи для вас. Следующие процентные модификаторы распознаются:% @,% c,% s,% d,% D,% i,% u,% U,% hi,% hu,% qi,% qu,% f,% g,% ld,% lu,% lld и% llu. Использование модификаторов, отличных от этих, приведет к непредсказуемым результатам. Если по какой-то причине вам требуется символ%, чтобы появиться в вашем операторе SQL, вы должны использовать %%.

Ответы [ 2 ]

7 голосов
/ 20 августа 2011
NSString *search_text = [NSString stringWithFormat:@"%%%@%%", theSearchQuery];

FMResultSet *rs = [db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE ?", search_text];
4 голосов
/ 24 июля 2011

Я бы настоятельно рекомендовал избегать создания запросов с помощью stringWithFormat :!Есть веская причина, почему FMDB пытается заставить вас использовать их очистку данных.Однако, поскольку FMDB упаковывает ваш ввод, окружающие скобки в следующем коде не нужны и могут вызвать вашу проблему.

[db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE (?)", theSearchQuery];

Простое добавление аргументов без скобок, потому что вы никогда не знаете, как FMDB блокирует ваш аргумент внутри.

[db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE ?", theSearchQuery];

Если это все еще не работает, попробуйте использовать предложенный метод executeQueryWithFormat: FMDB:

[db executeQueryWithFormat:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE %@", theSearchQuery];
...