Поведение SQLite на INSERT на iPhone - PullRequest
5 голосов
/ 14 сентября 2009

В настоящее время я делаю следующее как часть моего приложения для iPhone

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"cities.sqlite"];

sqlite3 *database;

if(sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) {
   const char *sqlStatement = "insert into table (name, description, image) VALUES (?, ?, ?)";
   sqlite3_stmt *compiledStatement;
   if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)    {
      sqlite3_bind_text( compiledStatement, 1, [name UTF8String], -1, SQLITE_TRANSIENT);
      sqlite3_bind_text( compiledStatement, 2, [description UTF8String], -1, SQLITE_TRANSIENT);
      NSData *dataForImage = UIImagePNGRepresentation(image);
      sqlite3_bind_blob( compiledStatement, 3, [dataForImage bytes], [dataForImage length], SQLITE_TRANSIENT);

   }
   if(sqlite3_step(compiledStatement) != SQLITE_DONE ) {
      NSLog( @"Error: %s", sqlite3_errmsg(database) );
   } else {
      NSLog( @"Insert into row id = %d", sqlite3_last_insert_rowid(database));
   }
   sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);

Что меня смущает, так это то, что если я вырежу раздел,

   if(sqlite3_step(compiledStatement) != SQLITE_DONE ) {
      NSLog( @"Error: %s", sqlite3_errmsg(database) );
   } else {
      NSLog( @"Insert into row id = %d", sqlite3_last_insert_rowid(database));
   }

ВСТАВКА не сохраняется в базе данных и теряется. Я предполагаю, что упускаю что-то очевидное здесь?

Ответы [ 4 ]

7 голосов
/ 14 сентября 2009

Конечно, это не будет вставлено. Вам нужно позвонить sqlite3_step , чтобы фактически выполнить ваше заявление.

Проверьте документацию out.

Это SQLITE, а не iPhone.

Из документации:

После того, как подготовленное заявление было подготовлен с использованием либо sqlite3_prepare_v2 () или sqlite3_prepare16_v2 () или один из устаревшие интерфейсы sqlite3_prepare () или sqlite3_prepare16 (), эта функция должен быть вызван один или несколько раз оценить утверждение.

2 голосов
/ 14 сентября 2009

Вы вставляете здесь только одну строку, поэтому здесь много шаблонного кода. Подумайте, что произойдет, если вы захотите вставить несколько строк:

  • Вам все равно понадобится одно подготовительное заявление
  • Вам все равно понадобится один оператор завершения
  • Вам понадобится один шаг для каждой строки, которую вы хотите добавить. Вы можете рассматривать «шаг» как «выполнить» (или «получить следующую строку», если вы смотрите на оператор SELECT)

Кстати, вы, вероятно, не хотите «шагать», если подготовленный оператор не удался.

2 голосов
/ 14 сентября 2009

Я бы полностью рекомендовал бы использовать оболочку вместо самостоятельной компиляции операторов ... Приличный список вариантов доступен здесь: http://cocoaheads.byu.edu/resources/sqlite

0 голосов
/ 30 октября 2012

Используйте код

const char *sqlStatement = "REPLACE INTO  table (name, description, image) VALUES (?, ?, ?)";

вместо «вставить в»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...