sqlite3“无法打开数据库文件” - ios

时间:2014-04-02 05:03:33

标签: ios objective-c sqlite

我在我的项目中使用sqlite3。

  • 在“无法打开”的一对(50-60)交易后,我收到错误 数据库文件“,所以检查我的数据库文件路径,但路径是正确的 文件就在那里。
  • 我尝试了在堆栈溢出时讨论的每个解决方案,但没有 运气。

  • 我检查了我的“ DocumentDirectory ”路径,在关闭数据库之前完成了所有必要的步骤。像:

      

    sqlite3_finalize(selectStatement);

         

    sqlite3_close(数据库);

  • 我不知道如何解决这个问题。我可以检查我的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;    
    }
    

3 个答案:

答案 0 :(得分:5)

数据库连接存在一个奇怪的问题,有时它无法连接。因此,人们建议您的应用程序应该打开一次数据库(在初始化阶段)并在应用程序终止时关闭连接。

参考: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 :(得分:3)

查看这种解决方案

首先创建如下函数:

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

    }

上面这对我很有帮助。试试这个。

答案 2 :(得分:0)

只需与我分享这个问题。

我有一个使用databaseFile1.sqlite的项目,我不确定模拟器上是否安装了该版本。

然后,我更改了数据库文件,说databaseFile2.sqlite的内容不同,文件名也不同。然后这个问题出现了。在阅读解决方案和评论时,我意识到问题不应该那么大。

欢迎,我删除了构建并重新启动了Xcode。瞧没关系稍后,我将恢复为databaseFile1.sqlite数据库,然后看看是否可以重现此问题。