невозможно открыть базу данных - PullRequest
1 голос
/ 31 июля 2010

Я использую приведенный ниже код для вставки данных в базу данных.и я вставляю приблизительно 15000 записей, но после 245 записей выдается ошибка «Невозможно открыть базу данных»

 +(void)addGeoRegions:(const char *)query geoId:(int)geoId geoFatherId:(int)geoFatherId geoName:(NSString *)geoName 
      geoTypeRegionId:(NSString *)geoTypeRegionId geoZone:(int)geoZone
    {
    sqlite3_stmt *dataRows = nil;
     @try {



     if(sqlite3_open([[self getDBPath] UTF8String],&PatientDatabase) == SQLITE_OK)
     {

      if (sqlite3_prepare_v2(PatientDatabase, query, -1, &dataRows, NULL)!=SQLITE_OK) 
      {
       NSAssert1(0,@"error while preparing  %s",sqlite3_errmsg(PatientDatabase));
      }

      sqlite3_bind_int(dataRows, 1, geoId);
      sqlite3_bind_int(dataRows, 2, geoFatherId);
      sqlite3_bind_text(dataRows, 3, [geoName UTF8String], -1, SQLITE_TRANSIENT);
      sqlite3_bind_text(dataRows, 4, [geoTypeRegionId UTF8String], -1, SQLITE_TRANSIENT);
      sqlite3_bind_int(dataRows, 5, geoZone);

      if (SQLITE_DONE!=sqlite3_step(dataRows))
      {
       char *err;
       err=(char *) sqlite3_errmsg(PatientDatabase);
       if (err)
        sqlite3_free(err);
       NSAssert1(0,@"error while inserting geo regions. %s",sqlite3_errmsg(PatientDatabase)); 

      }


     }

     }
     @catch (NSException * e) {

     }
     @finally 
     {
      sqlite3_close(PatientDatabase);
      sqlite3_finalize(dataRows);
      PatientDatabase=nil;
     }

    }

, поэтому, пожалуйста, любой может подсказать, почему возникает эта проблема.

Ответы [ 3 ]

1 голос
/ 31 июля 2010

Во-первых, подумайте над ответом Марка, вы получите лучшую производительность, если откроете базу данных один раз и закроете один раз.

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

 @finally 
 {
  sqlite3_close(PatientDatabase);  // will fail!
  sqlite3_finalize(dataRows);
  PatientDatabase=nil;
 }

Вот соответствующая строка из sqlite3_close () документов.

Приложения должны завершить все подготовленные операторы и закрыть все дескрипторы BLOB, связанные с объектом sqlite3, прежде чем пытаться закрыть объект. Если sqlite3_close () вызывается для соединения с базой данных, в котором все еще имеются ожидающие подготовленные операторы или дескрипторы BLOB, он возвращает SQLITE_BUSY.

Вам необходимо выполнить финализацию перед закрытием базы данных. При сложившейся ситуации вызов close завершается неудачей, и в результате вы получаете 245 открытых дескрипторов базы данных.

Итак, измените порядок двух операторов и проверьте ваши коды возврата на наличие ошибок.

Кстати, NSAssert не подходит для сообщения об ошибках. Выкиньте исключение или верните ошибку, или просто зарегистрируйте ее. NSAssert предназначен для выявления ошибок программирования. Он даже не будет скомпилирован в ваш код выпуска.

0 голосов
/ 30 марта 2014

Sqlite имеет гораздо лучшую производительность "в процессе" на вставках без транзакций. В частности, я часто использую процессы транзакций, или в какой-то момент происходит случайный сбой с ошибкой «невозможно открыть файл базы данных»

0 голосов
/ 31 июля 2010

Вы открываете базу данных при каждом вызове, потребуется один раз, чтобы открыть ее, а затем добавить все строки перед ее закрытием.Теоретически, то, что вы делаете, должно работать, но я бы даже не стал этим пользоваться.

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