【问题标题】:Sqlite database locked issue in iOSiOS中的Sqlite数据库锁定问题
【发布时间】:2015-04-03 04:48:19
【问题描述】:

我正在正确打开和关闭数据库。但是当我尝试在表中插入记录时,它仍然给出数据库锁定错误。请提出建议。

-(void)insertInDatabase:(NSMutableDictionary *) dict
{

    NSArray *dbPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,    NSUserDomainMask, YES);
    NSString *documentsDirectory = [dbPath objectAtIndex:0];
    NSString *DBPath=[documentsDirectory stringByAppendingPathComponent:@"InvoiceScannerDB.sqlite"];
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [appDelegate checkAndCreateDatabase: DBPath];

    sqlite3 * database;


    if(sqlite3_open([DBPath UTF8String], &database) == SQLITE_OK){
//      NSLog(@"open");
        NSString *sql = [[NSString alloc] initWithFormat:@"select *  from Ticket where DELIVERY_SEQ='%@'and DOC_DATE='%@' and ROUTE_CODE='%@'", [dict valueForKey:@"DELIVERY_SEQ"],[dict valueForKey:@"DOC_DATE"],[dict valueForKey:@"ROUTE_CODE"]];


        sqlite3_stmt *statement, *statement1, *statement2;

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

            NSLog(@"sqlite3_prepare_v2: %s", sqlite3_errmsg(database));

                //  NSLog(@"Statement %@",statement);
            if(sqlite3_step(statement) == SQLITE_ROW){
                NSLog(@"statement: %s", sqlite3_errmsg(database));

                    // Update Ticket for total scan count
                NSLog(@"Same record found in  local db");
                NSString *sqlUpdate = [[NSString alloc] initWithFormat:@"update Ticket set SCAN_INVOICE = '%ld' where DELIVERY_SEQ='%@'and DOC_DATE='%@' and ROUTE_CODE='%@'", (long)[[dict valueForKey:@"SCAN_INVOICE"] integerValue], [dict valueForKey:@"DELIVERY_SEQ"], [dict valueForKey:@"DOC_DATE"], [dict valueForKey:@"ROUTE_CODE"]];
                if(sqlite3_prepare_v2(database, [sqlUpdate UTF8String], -1, &statement2, NULL) == SQLITE_OK){

                    sqlite3_step(statement2);
                        //                  NSLog(@"Scan count updated successfully");

                }
                else{
                    NSLog(@"Not updated data");
                }
                sqlite3_finalize(statement2);
            }
            else {
                    // Insert
                NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
                dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
                [dateFormatter setDateFormat:@"dd-MMM-yyyy"];
                NSString *newDateString = [dateFormatter stringFromDate:[NSDate date]];

                NSString *sqlInsert = [[NSString alloc] initWithFormat:@"insert into Ticket (DELIVERY_SEQ, DOC_DATE, ROUTE_CODE, TOTAL_INVOICE, SCAN_INVOICE, InsertedDate) values('%@','%@', '%@','%ld','%ld', '%@')", [dict valueForKey:@"DELIVERY_SEQ"], [dict valueForKey:@"DOC_DATE"], [dict valueForKey:@"ROUTE_CODE"], (long)[[dict valueForKey:@"TOTAL_INVOICE"] integerValue], (long)[[dict valueForKey:@"SCAN_INVOICE"] integerValue], newDateString];

                NSLog(@"Insertion Query %@", sqlInsert);

                if(sqlite3_prepare_v2(database, [sqlInsert UTF8String], -1, &statement1, NULL) == SQLITE_OK){

                    if(sqlite3_step(statement1) == SQLITE_DONE)
                    {

                    } else {
                        NSLog(@"error: %s", sqlite3_errmsg(database));
                    }
                }
                else{
                        NSLog(@"Not inserted data");
                }
                sqlite3_finalize(statement1);
            }
        }
        else{
            NSLog(@"COULD NOT OPEN DB");
        }
        sqlite3_finalize(statement);
    }
    sqlite3_close(database);


}

请帮我解决这个问题

【问题讨论】:

  • 试试这个link可能是你的希望
  • 在哪一行你必须得到错误。
  • 一旦检查你的方法调用,是在不同的线程或主线程中
  • 感谢您的回复。我已经检查了该链接和所有打开关闭语句,但仍然面临同样的问题。
  • 它在主线程中运行。

标签: ios objective-c sqlite


【解决方案1】:

在完成原始statement 之前,您正在执行statement1statement2。在尝试执行INSERTUPDATE 之前,您应该关闭第一个SELECT 语句以测试是否有任何数据行。这可能不是繁忙数据库错误的实际来源,但它很好地说明了意外(且不必要地)同时执行两个 SQL 语句是多么容易。

如果修复此问题并不能消除错误,那么您必须有一些其他代码正在锁定数据库。我知道您向我们保证您已经检查了所有的打开和关闭语句并且您没有任何多线程数据库交互,但是“忙碌”消息意味着数据库只是忙于做其他事情,所以您有弄清楚这是怎么回事。

如果问题仍然存在,我可能会建议集中打开/关闭数据库(这样,很容易插入“是否已打开”检查)。坦率地说,我可能会更进一步,消除每次数据库交互时打开和关闭数据库的过程,但这取决于你。

【讨论】:

  • 感谢您的宝贵意见。现在我正在使用单个语句和重置语句来重用它。现在工作正常。
猜你喜欢
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
相关资源
最近更新 更多