无法打开数据库

时间:2010-07-31 09:09:12

标签: iphone objective-c sqlite

我使用下面的代码在数据库中插入数据。我正在插入aprox 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 个答案:

答案 0 :(得分:1)

首先,考虑一下Mark的答案,如果您打开数据库一次并关闭它,您将获得更好的性能。

无论如何,这是对设计改进的建议。你的代码实际上有什么问题是finally块:

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

以下是sqlite3_close()文档中的相关行。

  

应用程序必须在尝试关闭对象之前完成所有预准备语句并关闭与sqlite3对象关联的所有BLOB句柄。如果在仍具有未完成的预准备语句或BLOB句柄的数据库连接上调用sqlite3_close(),则返回SQLITE_BUSY。

您需要在关闭数据库之前运行finalize。事实上,关闭调用失败,最终得到245个打开的数据库句柄。

因此,请颠倒两个陈述的顺序,并检查您的退货代码是否失败。

顺便说一下,NSAssert不是报告错误的合适方式。抛出异常或返回错误,或只记录它。 NSAssert旨在捕获编程错误。它甚至不会被编译到您的发布代码中。

答案 1 :(得分:0)

Sqlite有更好的表现"在翻译"在没有交易的插入。我特别是,大量使用事务处理过程,或者在某些时候随机出现故障而导致错误"无法打开数据库文件"

答案 2 :(得分:-1)

您在每次调用时打开数据库,打开它所需的资源较少,然后在关闭之前添加所有行。理论上你正在做的事情应该有效,但这不是我开始使用的方式。