Как сохранить и получить NSdata в sqlite через FMDB

Как я могу сохранить NSData в sqlite, я использую оболочку FMDB для сохранения данных.

Ниже приведен код, который я пробовал до сих пор
Для сохранения

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:model.expertArray];; 
NSString *query = [NSString stringWithFormat:@"insert into save_article values ('%@','%@','%@','%@','%@','%@')",
                       model.Id, model.title, model.earliestKnownDate, data, model.excerpt,model.image_url];

Для извлечения

while([results next]) {
  NSData *data = [results dataForColumn:@"experts"];
        NSMutableArray *photoArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
 }     

Я пробовал оба типа данных и текст, но пока не повезло, может ли кто-нибудь помочь мне, как это сделать?


person DAMM108    schedule 06.03.2014    source источник
comment
Обычно NSData следует хранить в виде большого двоичного объекта. И с большим двоичным объектом вы в значительной степени должны использовать связанные параметры. В противном случае данные большого двоичного объекта (не ASCII) вызовут создание поврежденного оператора вставки.   -  person Hot Licks    schedule 06.03.2014
comment
Я тоже пытался с блобом, но это не работает   -  person DAMM108    schedule 06.03.2014
comment
(Кстати, если вы строите свои утверждения таким образом, вы на самом деле не используете FMDB, вы будете только обходить его.)   -  person Hot Licks    schedule 06.03.2014
comment
Вы должны использовать связанные параметры. Простая вставка большого двоичного объекта с stringWithFormat приводит к поврежденному оператору SQL.   -  person Hot Licks    schedule 06.03.2014
comment
Можете ли вы привести пример связанных параметров?   -  person DAMM108    schedule 06.03.2014
comment
Что сказал Рамди. Хотя есть несколько способов сделать это.   -  person Hot Licks    schedule 06.03.2014


Ответы (2)


Ниже приведен фрагмент для всех, кто может столкнуться с той же проблемой при вставке NSData в Sqlite с помощью FMDB.

В моем случае я хотел сохранить NSArray в Sqlite, поэтому я сначала преобразовал NSArray в NSData, а затем сохранил его в Sqlite.

Преобразование NSArray в NSData

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:YourNSarray];;

Сохранение NSData в Sqlite

[database executeQuery:@"insert into save_article values (?,?,?,?,?,?)", model.Id, model.title, model.earliestKnownDate, data, model.excerpt,model.image_url];

Примечание. Не создавайте запрос, используя stringWithFormat[ниже приведен код, который вам не следует использовать]:. Спасибо @rmaddy и @hotlicks за то, что указали мне на это :)

NSString *query = [NSString stringWithFormat:@"insert into user values ('%@', %d)",
@"brandontreb", 25];
[database executeUpdate:query];

и теперь последний шаг, то есть получение NSData обратно в NSArray

NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:[database dataForColumn:@"yourcololumname"]];

Надеюсь, это поможет нуждающимся и новичкам :)

person DAMM108    schedule 07.03.2014
comment
Что такое тип данных столбцов данных? - person delavega66; 26.03.2015
comment
Использовать большой двоичный объект для столбцов данных - person DAMM108; 27.03.2015
comment
ХОРОШО. Я понял. Спасибо за Ваш ответ. - person delavega66; 27.03.2015
comment
@ DAMM108 Я пробовал это, но у меня это не работает, даже если у меня есть тип данных blob. Есть ли еще какие-либо разъяснения, которые вы можете дать? Кроме того, вам не кажется, что запрос должен быть таким: Вставить в пользовательские (coulmn1, 2,3) значения (?,?,?)... - person MQ.; 17.04.2015

Не создавайте запрос, используя stringWithFormat:. Это плохая идея по нескольким причинам.

Используйте метод executeQuery, где вы ставите ? для каждого значения, которое будет привязано к запросу.

Что-то вроде этого:

[database executeQuery:@"insert into save_article values (?,?,?,?,?,?)", model.Id, model.title, model.earliestKnownDate, data, model.excerpt,model.image_url];
person rmaddy    schedule 06.03.2014
comment
какой тип данных я должен использовать, затем большой двоичный объект или текст - person DAMM108; 06.03.2014
comment
Используйте большой двоичный объект для NSData. - person rmaddy; 06.03.2014
comment
@rmaddy, не могли бы вы уточнить причины отказа от использования stringWithFormat? - person Eric Chuang; 05.03.2015
comment
@EricChuang Проблема в том, что если вы используете stringWithFormat:, значения могут содержать специальные символы, которые не экранированы должным образом. Это приводит к ошибкам и сбоям. Это также может привести к атакам с внедрением SQL (поищите по этому термину, если вы не знаете, что это такое). Правильно связывая значения, вы устраняете все эти проблемы. - person rmaddy; 05.03.2015
comment
@rmaddy я столкнулся с той же проблемой для stringWithFormat: при вставке строки, например ex. Это. это создает проблему при вставке, как это исправить? - person Avijit Nagare; 16.12.2015
comment
' необходимо экранировать, в sqlite он экранируется апострофом, поэтому в итоге он выглядит так: '' (2 апострофа, а не двойная кавычка), или вы можете использовать встроенные средства форматирования SQLite: char *result = sqlite3_vmprintf("%Q", variadic params);. %q и %Q, скорее всего, то, что вам нужно. sqlite имеет несколько разных версий sqlite3_*printf. Как отмечали другие, безопаснее просто использовать привязку операторов, тогда вам не нужно об этом беспокоиться. sqlite.org/c3ref/mprintf.html - person AJ Venturella; 20.01.2016
comment
Итак, если бы я строил запрос, как в вашем примере, мне нужно было бы передавать значения в том порядке, в котором они находятся в таблице? @rmaddy - person Hemang; 10.09.2016
comment
@Hemang Лучшее решение - указать имена столбцов в SQL: INSERT INTO table_name (col1, col2, col3) VALUES (?, ?, ?). Затем значения должны передаваться в порядке, указанном в операторе INSERT. - person rmaddy; 10.09.2016
comment
выполнить обновление, а не выполнить запрос - person Andrey Chernukha; 01.11.2018