2014-04-02 87 views
2

我在我的項目中使用sqlite3。sqlite3「無法打開數據庫文件」 - ios

  • 我交易的夫婦(50-60)後收到錯誤「無法打開 數據庫文件」,所以,檢查我的數據庫文件的路徑,但路徑是正確的, 文件是存在的。
  • 我試過在棧溢出上討論的每一個解決方案,但沒有運用

  • 我檢查我的「DocumentDirectory」路徑,完成關閉數據庫之前的所有必要步驟。像:

    sqlite3_finalize(selectStatement);

    sqlite3_close(database);

  • 我不知道如何解決這個問題。 我可以檢查我的sqlite3數據庫是否打開

    ====================== 1 ======================= =====

    +(NSMutableArray*)executeDataSet:(NSString*)query 
        { 
          NSMutableArray *arryResult = [[NSMutableArray alloc] initWithCapacity:0]; 
    
    
         const char *sql = [query UTF8String]; 
         sqlite3_stmt *selectStatement; 
          sqlite3 *database = [DataBaseClass openDataBase]; 
    
         //prepare the select statement 
         int returnValue = sqlite3_prepare_v2(database, sql, -1, &selectStatement, NULL); 
         if(returnValue == SQLITE_OK) 
         { 
          //my code 
         } 
    
         } 
         //sqlite3_reset(selectStatement); 
          // NILOBJECT(selectStatement); 
         // NILOBJECT(selectStatement); 
         sqlite3_finalize(selectStatement); 
         sqlite3_close(database); 
    
         return arryResult; 
        } 
    

    ==================== 2 ================= ================

    +(sqlite3 *) openDataBase { 
         sqlite3 * edenAdultDatabase; 
         NSString * databasePath =[DataBaseClass pathForDatabase]; 
    
         if(sqlite3_open([databasePath UTF8String], &edenAdultDatabase) == SQLITE_OK) { 
    
          NSLog(@"Yes database is open"); 
          return edenAdultDatabase; 
         } 
         else 
          { 
          NSLog(@"do something %s",sqlite3_errmsg(edenAdultDatabase)); 
          } 
         return edenAdultDatabase; 
    
        } 
    

    ====================== 3 ==== =======================

    +(NSString *) pathForDatabase { 
        NSString *libraryDir = [FileManager pathForPrivateDocumentsFolder]; 
    
        NSFileManager *fileMgr = [NSFileManager defaultManager]; 
    
        NSError *error; 
    
        NSString *privateFolderPath = [libraryDir stringByAppendingPathComponent:@"DataBase"]; 
    
        if (![fileMgr fileExistsAtPath:privateFolderPath]) 
        { 
         [fileMgr createDirectoryAtPath:privateFolderPath withIntermediateDirectories:NO attributes:nil error:&error]; 
        } 
    
        /* 
        // My database in library private folder ..this is just for test. 
        // I copied databae to document dir but no luck. 
        NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
        NSString *documentsDir = [documentPaths objectAtIndex:0]; 
        privateFolderPath = [documentsDir stringByAppendingPathComponent:kDatabaseName]; 
        */ 
    
        privateFolderPath = [privateFolderPath stringByAppendingPathComponent:kDatabaseName]; 
    
        return privateFolderPath;  
    } 
    
+0

問題可能在於您尚未與我們分享的部分代碼。您沒有向我們展示哪一行報告了您報告的錯誤。我想知道是否有一些路徑可以打開數據庫,但忽略關閉它。此外,記錄每一次關閉(這樣可以確保開放和關閉語句正確配對)。如果打開失敗,我可能會建議記錄錯誤(現在,如果打開失敗,它將保持沉默,這在您的日誌中很難識別)。順便說一句,沒有必要爲每個數據庫交互打開和關閉數據庫。 – Rob

+0

另外,您可能要認真考慮[FMDB](https://github.com/ccgus/fmdb),它簡化了SQLite編程。 – Rob

+0

@Rob sqlite3_close(database); NSLog(@「database close%d」,sqlite3_close(database)); //給我21是好的。 –

回答

4

數據庫連接存在一個奇怪的問題,有時它不會連接。因此,人們建議您的應用程序應該打開一次數據庫(在初始化階段),並在應用程序終止時關閉連接。

參考:Sqlite opening issue

關於檢查數據庫連接,SQLITE3不提供任何方法來檢查,要麼數據庫是打開或沒有。

通過使用數據庫管理器的共享實例,您可以實現它。定義在類級別的布爾並設置它的價值,當你打開數據庫:

// .h file 
BOOL isDatabaseOpen; 

// .m file 
-(void) openDatabase 
{ 
    if(![self isDatabaseExist]) 
    { 
     // copy database to library 
     [self copyDatabaseFile]; 
    } 

    NSString *sqLiteDb = [self getDatabaseLibraryPath]; 
    if (sqlite3_open([sqLiteDb UTF8String], &_databaseHandler) != SQLITE_OK) { 
     NSLog(@"Database --> Failed to open"); 
     isDatabaseOpen = NO; 
    } 
    else 
    { 
     isDatabaseOpen = YES; 
    } 
} 

,然後你可以用下面的方法來檢查的數據庫打開與否。

-(BOOL) isDatabaseOpen 
{ 
    return isDatabaseOpen; 
} 

讓我知道它是否工作:)。

+1

不錯的主意和不錯的工作!我在每個查詢中打開我的數據庫。從一個14k數據集的循環中只保存3k數據庫..打開數據庫一次(!)保存了全部14k。謝謝! – Rikco

2

退房這種解決方案

首先像下面創建功能:

-(void)checkDBAndCopy{ 

NSArray *dirPath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); 
NSString *connectionPath=[dirPath objectAtIndex:0]; 
strDBPath=[connectionPath stringByAppendingPathComponent:@"database.sqlite"]; 
NSLog(@"%@",strDBPath); 
NSFileManager *filemanager=[[NSFileManager alloc]init]; 
if (![filemanager fileExistsAtPath:strDBPath]) { 
    NSString *databasePathFromApp=[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:@"database.sqlite"]; 

    [filemanager copyItemAtPath:databasePathFromApp toPath:strDBPath error:nil]; 
} 
} 

,並調用該函數類似下面的方法: -

-(NSMutableArray *)RetriveSharedspots:(NSString *)Query{ 

[self checkDBAndCopy]; 

if (sqlite3_open([strDBPath UTF8String], &contactDB)==SQLITE_OK) { 

    sqlite3_stmt *statement; 

    if (sqlite3_prepare_v2(contactDB, [Query UTF8String],-1,&statement,NULL)==SQLITE_OK)   
     { 

     while (sqlite3_step(statement)==SQLITE_ROW) { 

      // Your code 
     } 
    } 
    sqlite3_finalize(statement); 
} 
sqlite3_close(databaseName); 

return array; 

    } 

高於這個工作對我來說大。嘗試這個。

相關問題