尝试更新和插入时数据库被锁定

时间:2014-03-06 12:32:45

标签: c++ ios iphone objective-c sqlite

当我尝试插入或更新时,数据库会被随机锁定。我正在提供我正在使用的代码。如果除此之外还需要做其他事情,请告诉我。

由于数据库的打开和关闭功能,我读了一些发生此问题的地方。请告诉我这是什么问题?

-(BOOL)createDB : (const char *)str {
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: @"SpotLogic.db"]];
BOOL isSuccess = YES;
// NSFileManager *filemgr = [NSFileManager defaultManager];
    dbpath = [databasePath UTF8String];
    if (sqlite3_open(dbpath, &database) == SQLITE_OK)
    {
        char *errMsg;
        const char *sql_stmt = str;
        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");
    }
return isSuccess;
}


- (BOOL)deleteData:(NSString *)deleteSql
{
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: @"SpotLogic.db"]];
dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
    const char *insert_stmt = [deleteSql UTF8String];
    sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
    if (sqlite3_step(statement) == SQLITE_DONE)
    {
        return YES;
        NSLog(@"deleted");
    }
    else {
        NSLog(@"Not deleted");
        return NO;
    }
    sqlite3_reset(statement);
}
return NO;
}


- (BOOL)insertData:(NSString *)insertSQL
{
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: @"SpotLogic.db"]];
dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
        if (sqlite3_step(statement) == SQLITE_DONE)
        {
            return YES;
            NSLog(@"inserted");
        } 
        else {
            NSLog(@"Not inserted");
            return NO;
        }
        sqlite3_reset(statement);
    }
return NO;
}


- (sqlite3_stmt *)fetchData:(NSString *)fetchSQL
{
NSLog(@"%@",fetchSQL);
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: @"SpotLogic.db"]];
 // array = [[NSMutableArray alloc]init];
dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
    const char *fetch_stmt = [fetchSQL UTF8String];
    if(sqlite3_prepare_v2(database, fetch_stmt,-1, &statement, NULL)==SQLITE_OK)
    {
        sqlite3_reset(statement);
    }
    else
    {

    }
}
return statement;
   }


- (BOOL)update:(NSString *)insertSQL
{
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: @"SpotLogic.db"]];
 dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
    const char *insert_stmt = [insertSQL UTF8String];
    sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
    if (sqlite3_step(statement) == SQLITE_DONE)
    {
        return YES;
        NSLog(@"inserted");
    }
    else {
        NSLog(@"Not inserted");
        return NO;
    }
    sqlite3_reset(statement);
}
return NO;
}

我实际上发现了这个问题。我运行此代码时,我的数据库被锁定。

 for(int i = 0 ; i < meeting_ids.count ; i ++){
    statement = [[DataManger getSharedInstance] fetchData:[NSString stringWithFormat:@"SELECT red_flag FROM meeting_question WHERE meeting_id = '%@'",[meeting_ids objectAtIndex:i]]];

    while (sqlite3_step(statement) == SQLITE_ROW)
    {
        char *field1=(char *) sqlite3_column_text(statement, 0);
        NSString *name =[[ NSString alloc]initWithUTF8String:field1];
        NSLog(@"%@",name);
        if([name isEqualToString:@"1"]){
            [red_flag replaceObjectAtIndex:i withObject:@"1"];
            break;
        }
    }
   }

这与for循环是原因。 我必须通过'meeting_ids'数组中的会议ID与所有会议中获得'red_flag'。 任何其他方式来做到这一点

2 个答案:

答案 0 :(得分:0)

试试这个:

如果每次都打开数据库,那么每次都要关闭它。

所以,写一下......

sqlite3_close(database);

这一行在所有功能中。

答案 1 :(得分:0)

运行语句后,请使用这两个语句进行reset和finalize语句,然后关闭数据库。

sqlite3_reset(statement);
sqlite3_finalize(statement);
sqlite3_close(database);