Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
308 views
in Technique[技术] by (71.8m points)

iphone - unable to open database

I am using below code for inserting data in the database. and i am inserting aprox 15000 records but after 245 records it throws the error "Unable to open database"

 +(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;
     }

    }

so please can any one suggest why this problem is occur.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Firstly, think about Mark's answer, you'll get better performance if you open the database once and close it once.

Anyway, that was a suggestion for a design improvement. What is actually wrong in your code is the finally block:

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

Here is the relevant line from the sqlite3_close() docs.

Applications must finalize all prepared statements and close all BLOB handles associated with the sqlite3 object prior to attempting to close the object. If sqlite3_close() is called on a database connection that still has outstanding prepared statements or BLOB handles, then it returns SQLITE_BUSY.

You need to run the finalize before closing the database. As things stand, the close call fails and you end up with 245 open database handles.

So, reverse the order of the two statements and check your return codes for failure.

By the way, NSAssert is not an appropriate way to report errors. Throw an exception or return an error, or just log it. NSAssert is designed to catch programming errors. It won't even be compiled into your release code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...