2013-06-19 2 views
1

Я получаю следующее сообщение об ошибке при попытке вставить данные в моей базе данных SQLite:санировать Строки перед вставкой в ​​БД

"sqlite near "t": syntax error" 

, и я понятия не имею, что это значит :-(

Справочная информация: Я использую mysql_real_escape_string для «дезинфекции» данных, поступающих из онлайн-формы (форма предлагает пользователю ввести информацию в текстовые поля и нажать «отправить») - и это работает отлично: это позволяет использовать все одно и два цитируемые символы должны быть приняты и введены в БД без ошибок.

Затем мое приложение iPhone запрашивает эту БД и анализирует входящие данные - и интересно то, что я тогда получаю «и» повсюду (как: «не» или «Одиссея» of not or «The Odyssey»)

Чтобы исправить это, я использую [stringVar stringByReplacingOccurrencesOfString:@"\\" withString:@""] - так что я в основном заменяю все косые черты без пробелов - и это отлично работает (я получаю: не делаю + «Одиссея», .)

ОДНАКО, когда я сейчас пытаюсь пойти и НАПИСАТЬ эти недавно загруженные и проанализированные данные на мой на устройстве sqlite database - приложение аварийно завершает работу. И я вполне уверен, что это связано с их единственными & двойными кавычками, косыми чертами, и кто знает, что еще.

Чтобы проверить что-то, я создал несколько быстрых фиктивных данных, которые НЕ содержат каких-либо из этих хитрых символов, вставляют их в базу данных (во время выполнения), и все работает отлично - приложение не сбой, база данных sqlite устройства показала все хорошо - так что я уверен, что нет ничего плохого в моей базе данных sqlite, моих SQL-операторах и т. д. Это должны быть загруженные данные/строки, которые все еще повреждены.

Само собой разумеется, что я не эксперт по SQL - я в основном знаю, что голый минимум может пройти и попытаться научиться чему-либо, когда я пойду. Я исследовал это и думал, что нашел решение с mysql_real_escape_string, но, похоже, он работает только в одном направлении - за исключением того, что мне нужно решение «туда и обратно».

любые советы или предложения?

======================================

EDIT # 1 - вот код, я использую - гибрид, что было предложено, и что я нахожу в этой книге iPhone:

NSString *sqlString = [NSString stringWithFormat:@"INSERT OR REPLACE INTO '%@' ('%@', '%@', '%@', '%@') VALUES (?, ?, ?, ?)", tableName, @"Title", @"Source", @"Date", @"StoryCopy"]; 

NSLog(@"The sql string is = '%@'", sqlString); 
const char *sql = [sqlString UTF8String]; 
sqlite3_stmt *stmt; 
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nil); 
if (rc == SQLITE_OK) { 
    sqlite3_bind_text(stmt, 0, [sTitle UTF8String], -1, SQLITE_TRANSIENT); 
    sqlite3_bind_text(stmt, 1, [sSource UTF8String], -1, SQLITE_TRANSIENT); 
    sqlite3_bind_text(stmt, 2, [sDate UTF8String], -1, SQLITE_TRANSIENT); 
    sqlite3_bind_text(stmt, 3, [sCopy UTF8String], -1, SQLITE_TRANSIENT); 
} 

if (sqlite3_step(stmt) != SQLITE_DONE) { 
    NSAssert(0, @"Error updating table!!!"); 
} 

sqlite3_finalize(stmt); 

проблема заключается в том, что ее значения в вставка столбцов не следует вставлять в. Это своего рода повсюду. Какие-нибудь идеи, что здесь не так?

+0

Индексы столбцов, переданные в функции 'sqlite3_bind_xxx', начинаются с 1, а не 0. К сожалению, индексы столбцов для функций' sqlite3_column_xxx' основаны на 0. Это запутанно и подвержено ошибкам. Кроме того, почему вы используете формат строки для имен таблиц и столбцов? Просто поместите имена прямо в строку запроса. И имена не нужно указывать. – rmaddy

+0

Я вижу - хорошо знать - я исправил его и теперь хорошо себя зарекомендовал (спасибо!) Re, используя строковый формат для имен таблиц и столбцов - мое первоначальное намерение состояло в том, чтобы сделать этот метод достаточно гибким, чтобы я мог называть его ЛЮБОЙ из таблиц в моей БД (отсюда «tableName») - все они имеют разные столбцы в em. Но код прошел через QUITE несколько изменений начиная с :-) (Как сейчас, с вашими исправлениями.) Так что это немного беспорядочный беспорядок со всяким барахлом. Честно говоря, прямо сейчас я просто счастлив заставить его работать над этой одинокой таблицей - и если мне приходится писать индивидуальные методы для каждой таблицы, пусть будет так :-) – sirab333

ответ

3

Похоже, что вы неправильно выполняете свои запросы. Вначале нет необходимости «санировать» что-либо. Убедитесь, что вы не используете строковые форматы для создания запроса. Вместо этого следует использовать функции sqlite3_bind_xxx.

Пример:

sqlite3_stmt *stmt; 
int rc = sqlite3_prepare_v2(dbHandle, "INSERT INTO table_name (field1, field2) VALUES (?, ?)", -1, &stmt, nil); 
if (rc == SQLITE_OK) { 
    sqlite3_bind_text(stmt, 1, [someValue UTF8String], -1, SQLITE_TRANSIENT); 
    sqlite3_bind_text(stmt, 2, [otherValue UTF8String], -1, SQLITE_TRANSIENT); 
} 

someValue, где и otherValue являются NSString объектами. Текст может содержать любой текст в Юникоде. Использование sqlite_bind_text позволяет избежать любых символов, которые необходимо экранировать.

Позже, прочитав значения из запроса с помощью sqlite3_column_text, вы получите исходный текст.

+1

... и то же самое относится к стороне PHP: Используйте готовые заявления вместо ужасного хака 'mysql_real_escape_string'. –

+0

ОК, работая над ним, но когда вы написали 'sqlite3_statement * stmt;' вы имели в виду 'sqlite3_stmt * stmt;'? – sirab333

+0

Да, я только что установил опечатку - спасибо. – rmaddy

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