【问题标题】:Getting database locked error while adding row 2nd time [duplicate]第二次添加行时出现数据库锁定错误[重复]
【发布时间】:2016-07-22 19:46:04
【问题描述】:

我收到错误数据库锁定。 在第一次尝试它添加行但之后我收到错误 database locked

我正在尝试制作网页保护程序,因此在第一次加载应用程序时它正在添加行但是当我再次尝试保存任何网页时它没有保存并且我正在锁定错误数据库。

保存一个网页后,即使删除也不会发生。

#import "DBManager.h"
static DBManager *sharedInstance = nil;
static sqlite3 *database = nil;
static sqlite3_stmt *statement = nil;

 @implementation DBManager

 +(DBManager*)getSharedInstance{
if (!sharedInstance) {
    sharedInstance = [[super allocWithZone:NULL]init];
    [sharedInstance createDB];
}
return sharedInstance;
}

-(BOOL)createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent: @"browser.db"]];

BOOL isSuccess = YES;
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
    const char *dbpath = [databasePath UTF8String];
    if (sqlite3_open(dbpath, &database) == SQLITE_OK)
    {
        char *errMsg;
        NSLog(@"insod");
        const char *sql_stmt ="create table if not exists list(sno int primary key,name varchar(50),category varchar(30),path varchar(500),fav int)";
        if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg)
            != SQLITE_OK)
        {
            isSuccess = NO;
            NSLog(@"Failed to create table");
        }
        sqlite3_close(database);
        return  isSuccess;
    }
    else {
        isSuccess = NO;
        NSLog(@"Failed to open/create database");
    }
}else{
    NSLog(@"File Exist");
}
return isSuccess;
 }

 -(BOOL) Delete:(NSString *) name{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK){
    NSString *query = [NSString stringWithFormat:@"delete from list where name like '%@'",name];
    const char *stmt = [query UTF8String];
    sqlite3_prepare_v2(database, stmt,-1, &statement, NULL);
    if (sqlite3_step(statement) == SQLITE_DONE){
        sqlite3_finalize(statement);
        return YES;
    }else {
         NSLog(@"error: %s",sqlite3_errmsg(database));
        sqlite3_finalize(statement);
        return NO;
    }

}else{
    sqlite3_close(database);
    return NO;
}

 }

-(NSDictionary *) CatList:(NSString *) cat{
const char *dbpath = [databasePath UTF8String];
NSDictionary *dict;
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{

    NSString *querySQL =[NSString stringWithFormat:@"select name,path from list where category like '%@'",cat];
    const char *query_stmt = [querySQL UTF8String];

    if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
    {
       // NSLog(@"inside list");

        NSMutableArray *arr1 = [[NSMutableArray alloc] init];
        NSMutableArray *arr2 = [[NSMutableArray alloc] init];
        //            NSMutableArray *arr3 = [[NSMutableArray alloc] init];
        while(sqlite3_step(statement) == SQLITE_ROW)
        {

            NSString *name = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
            [arr1 addObject:name];
            //NSLog(@"%@",name);
            NSString *category = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
            [arr2 addObject:category];
            //                //NSLog(@"%@",dept);
            //                NSString *path = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
            //                [arr3 addObject:path];
        }
        sqlite3_finalize(statement);
        dict = @{@"name":arr1,@"path":arr2};
        //NSLog(@"%@",dict);
    }else{
        NSLog(@"error: %s",sqlite3_errmsg(database));
    }
    sqlite3_close(database);
}
return dict;
 }

 - (BOOL) saveData:(NSString*)name category:(NSString*)category path:(NSString*)path{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{

    NSString *highest = @"select max(sno) from list";
    const char *Query = [highest UTF8String];

    if (sqlite3_prepare_v2(database, Query, -1, &statement, NULL) == SQLITE_OK){
        if (sqlite3_step(statement) == SQLITE_ROW){
            int sno = sqlite3_column_int(statement, 0);
            NSString *insertSQL = [NSString stringWithFormat:@"insert into list values(\"%d\",\"%@\",\"%@\", \"%@\",\"%d\")",sno+1,name, category, path,0];
            const char *insert_stmt = [insertSQL UTF8String];
            sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
            if (sqlite3_step(statement) == SQLITE_DONE){
                sqlite3_finalize(statement);
                return YES;
            }else {
                sqlite3_finalize(statement);
                return NO;
            }

        }else{
            NSString *insertSQL = [NSString stringWithFormat:@"insert into list values(\"%d\",\"%@\",\"%@\", \"%@\",\"%d\")",1,name, category, path,0];
            const char *insert_stmt = [insertSQL UTF8String];
            sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
            if (sqlite3_step(statement) == SQLITE_DONE){
                sqlite3_finalize(statement);
                return YES;
            }else {
                sqlite3_finalize(statement);
                return NO;
            }
        }
    }
    sqlite3_close(database);
}
return NO;
 }

 -(BOOL) Fav:(NSString *) name{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK){
    NSString *query = [NSString stringWithFormat:@"update list set fav = 1 where name like '%@'",name];
    const char *stmt = [query UTF8String];
    sqlite3_prepare_v2(database, stmt,-1, &statement, NULL);
    if (sqlite3_step(statement) == SQLITE_DONE){
        sqlite3_finalize(statement);
        return YES;
    }else {
        sqlite3_finalize(statement);
        return NO;
    }
}else{

    return NO;
}
 }

 -(NSArray *) GetListFav{
const char *dbpath = [databasePath UTF8String];
NSArray *dict;
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{

    NSString *querySQL = @"select name from list where fav = 1";
    const char *query_stmt = [querySQL UTF8String];

    if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
    {
        NSMutableArray *arr1 = [[NSMutableArray alloc] init];
        while(sqlite3_step(statement) == SQLITE_ROW)
        {
            NSString *name = [[NSString alloc] initWithUTF8String:              (const char *) sqlite3_column_text(statement, 0)];
            [arr1 addObject:name];
        }
        sqlite3_finalize(statement);
        dict = arr1;
    }else{
        NSLog(@"error: %s",sqlite3_errmsg(database));
    }
    sqlite3_close(database);
}
return dict;
 }

 -(BOOL) removeFav:(NSString *) name{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK){
    NSString *query = [NSString stringWithFormat:@"update list set fav = 0 where name like '%@'",name];
    const char *stmt = [query UTF8String];
    sqlite3_prepare_v2(database, stmt,-1, &statement, NULL);
    if (sqlite3_step(statement) == SQLITE_DONE){
        sqlite3_finalize(statement);
        return YES;
    }else {
        sqlite3_finalize(statement);
        return NO;
    }

}else{
    return NO;
}
}

 -(NSArray *) GetList{
const char *dbpath = [databasePath UTF8String];
NSArray *dict;
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{

    NSString *querySQL = @"select name from list";
    const char *query_stmt = [querySQL UTF8String];

    if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
    {
        //NSLog(@"inside list");

        NSMutableArray *arr1 = [[NSMutableArray alloc] init];
        while(sqlite3_step(statement) == SQLITE_ROW)
        {
            NSString *name = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
            [arr1 addObject:name];
        }
        sqlite3_finalize(statement);
        dict = arr1;
    }else{
        NSLog(@"error: %s",sqlite3_errmsg(database));
    }
    sqlite3_close(database);
}
return dict;
  }

 @end

【问题讨论】:

    标签: ios objective-c iphone sqlite


    【解决方案1】:

    您一次只能访问一次 sqllite。如果你有多个线程,你可以在这种情况下运行。示例:

    因此,一旦使用数据库,请务必尝试关闭:

    sqlite3_close(database);
    

    【讨论】:

      【解决方案2】:

      在再次尝试 sqlite3_open 之前,您需要确保每个 sqlite3_open 都与 sqlite3_close 平衡:

      1. 您的saveData 方法有很多return 语句会阻止数据库调用sqlite3_close。确保方法之外的所有路径都正确关闭数据库。最后,这意味着你会尝试打开数据库,尽管它已经打开了。

        或者,更好的是,只打开一次数据库就保持打开状态,省去了重复打开和关闭数据库的麻烦。

      2. 您的 DeleteFavremoveFav 方法也没有关闭数据库。

      一些不相关的观察:

      1. 您应该警惕使用stringWithFormat 来构建带有字符串参数的SQL。如果要搜索的字符串中有撇号,您的代码将失败。使用? 占位符,然后使用sqlite3_bind_text 将值绑定到这些占位符。

      2. 如果您将sno 列设为AUTOINCREMENT,则不必执行“在插入新行之前获取最大sno”逻辑。因此,CREATE 语句可能如下所示:

        create table if not exists list (
            sno integer primary key autoincrement, 
            name text, 
            category text, 
            path text, 
            fav integer)
        

        然后您可以在 INSERT 语句中省略 sno,它会自动分配一个唯一标识符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-14
        • 2012-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-10
        • 2011-08-24
        相关资源
        最近更新 更多