2010-07-31 99 views
1

我正在使用下面的代碼在數據庫中插入數據。而我將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; 
    } 

    } 

所以請任何一個能說明爲什麼這個問題會發生。

+0

儀器在內存使用情況方面顯示了什麼? – 2010-07-31 09:10:34

+1

呃。你爲什麼不使用核心數據?它非常適合這種任務。 – bbum 2010-07-31 18:04:57

回答

1

首先,考慮馬克的答案,如果您打開一次數據庫並關閉一次,您將獲得更好的性能。

無論如何,這是一個設計改進的建議。什麼是你的代碼實際上錯的是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在插入時沒有事務處理,在「轉換」中有更好的性能。特別是,大量使用交易過程或故障隨機出現,並出現錯誤「無法打開數據庫文件」