2010-08-30 3 views

ответ

5

Как вы нашли, просто используя один и тот же текст в качестве имени переменной и в качестве подстроки строки буквального не вызывает содержимое переменной быть сращены в строку. Компилятор теоретически может установить это для вас, но он не делает этого без явных символов форматирования, не является признаком какого-либо языка, о котором я когда-либо слышал. Даже если это было поддержано, вы все равно не смогли бы объединить объекты NSString в строки C.

Итак, вопрос заключается в том, как объединить строку из str в строку запроса.
Ответ неstringWithFormat:!

Это открывает вам SQL-инъекцию, которая в контексте базы данных, к которой пользователь обращается с той же машины, на которой он находится, означает, что пользователь может испортить свои данные, введя неправильную вещь. Попытка исправить это, ускользнув от вещей, - это бесконечная игра с ударом-молью и неуверенностью в себе («Я надеюсь, что это последняя из этих ошибок»).

Правильное решение - позволить SQLite сплайсировать параметры в запрос, поскольку только он знает, как это сделать. Вы делаете это, готовя инструкцию с вопросительным знаком в каждой точке, где вам нужно сращиться в значении, затем binding the value(s) into the statement. Каждый вызов одной из функций связывания заменяет один не привязанный заполнитель тем, что значение, которое вы передаете, безопасно, то есть не будет создавать недопустимый или деструктивный запрос.

+0

1+ Питер хороший. –

3
NSString *[email protected]"mac"; 

NSString *sql =[NSString stringWithFormat:@"select rowid from mytable where name = %@",str]; 
if (sqlite3_prepare_v2(database, [sql UTF8String], -1, &select_statement, NULL) != SQLITE_OK) 
{ 
    NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database)); 
} 
+0

не получилось правильно ответить – user426795

+0

Попробуйте это. (Я отредактировал код и внедрил новый код). Это код, который я использую с долгого времени. Не знаю, почему он не работает для вас. –

+2

Если 'str' приходит из текстового поля или другого пользовательского ввода, это плохая идея, потому что это уязвимость SQL-инъекции. В этом случае пользователь вряд ли сделает что-то вредоносное для своих собственных данных, но они все равно могут его испортить. –

1

@Peter Hosey абсолютно прав: путь для этого - это функции связывания SQLite. Тем не менее, даже лучше способ сделать это, чтобы использовать обертку как FMDB или TouchSQL, которые оба позволяют использовать stringWithFormat:стиля синтаксиса, но в то же время с помощью связывания функций снизу. Другими словами, они делают все, что вы хотите сделать, но уже сделали это для вас и (без обид), скорее всего, сделали это лучше, чем вы.

Смежные вопросы