iOS SQLite3数据库已被锁定

时间:2015-01-20 13:53:18

标签: ios objective-c database sqlite

  1. 我有一个包含超过2000个数组的JSON文件,并且在每个数组中可能有一个包含5个字符串的数组。

  2. 我在一个函数中运行了两个for()循环,所以我认为2ed将在第一个函数完成后运行?

    有时会出现以下情况(出现随机数据错误):

      

    数据库被锁定

    我正在执行

    INSERT INTO problemTags(problem_IDIndex)VALUES('93E')
    

  3. 我使用下面的代码来执行我的SQL语句

    + (void)execSqliteWithSQL:(NSString *)sql{
        sqlite3 *sqlite = nil;
        int openResult = sqlite3_open([DBPath UTF8String], &sqlite);
        if(openResult != SQLITE_OK){
            NSLog(@"open DB error");
        }
        char *error;
        int execResult = sqlite3_exec(sqlite, [sql UTF8String], nil, nil, &error);
        if(execResult != SQLITE_OK){
            NSString *errorString = [NSString stringWithFormat:@"\n execResult error=>\n %s \n SQL:\n%@\n",error,sql];
            NSLog(@"%@",errorString);
        }
        sqlite3_close(sqlite);
    }
    

    我在考虑这个问题的原因是什么 当我运行for循环时,它会向execSqliteWithSQL函数发送几个SQL语句,当它运行得不够快时,数据库会被关闭吗?


    下面提出的问题:

    不使用主题 两个for循环如下所示:

    -(void)......{
        for(){
           //sending SQL to execSqliteWithSQL
        }
    
        for(){
           //sending SQL to execSqliteWithSQL
        }
    
     }
    

1 个答案:

答案 0 :(得分:0)

有几点想法:

  1. 您是否可能同时调用此execSqliteWithSQL多个线程?如果是这样,很可能会出现这样的错误。

    您可以通过设置execSqliteWithSQL将调度其呼叫的专用串行队列来解决此问题,从而消除同时执行此操作的尝试。

  2. 无论如何,我建议不要为每次通话打开和关闭数据库。这非常低效。

    事实上,如果做一堆更新/插入语句,你不仅不想为每次调用打开和关闭数据库,而是想要打开,调用BEGIN TRANSACTION,进行更新,然后COMMIT这些变化。性能差异令人吃惊。

  3. 这个execSqliteWithSQL显然预先假定您手动构建SQL(可能是stringWithFormat)。这充其量是问题,最坏的情况是危险的。如果在插入数据库的字符串值中出现引号,则SQL将失败。如果此订阅源包含任何用户输入,则您很容易受到SQL注入攻击。

    相反,您应该使用sqlite3_prepare_v2准备带有?占位符的SQL语句,然后使用sqlite3_bind_xxx将值绑定到这些占位符。