2013-02-20 46 views
0

我試過很多方法,爲了擺脫這個錯誤,但是我沒有成功。我是一個新手,我試圖找出所有其他問題,並嘗試了一些建議,但它沒有奏效。iphone-sqlite3數據庫鎖定異常

下面是代碼:

- (void) addObiectAsigurat 
{ 
sqlite3 *database = nil; 
sqlite3_stmt *addStmt = nil; 

if(sqlite3_open([[Database getDBPath] UTF8String], &database) == SQLITE_OK) 
{ 

    if(addStmt == nil) { 
     const char *sql = "INSERT INTO ObiectAsigurat (IdIntern, TipObiect, JSONText) Values(?, ?, ?)"; 
     if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK) 
      NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database)); 
    } 

    sqlite3_bind_text(addStmt, 1, [IdIntern UTF8String], -1, SQLITE_TRANSIENT); 
    sqlite3_bind_int(addStmt, 2, TipObiect); 
    sqlite3_bind_text(addStmt, 3, [JSONText UTF8String], -1, SQLITE_TRANSIENT); 


    if(SQLITE_DONE != sqlite3_step(addStmt)) 
     NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database)); 
    else { 
     sqlite3_finalize(addStmt); 
     sqlite3_close(database); 
    } 

如果我用這個這個方法結束


} 
else sqlite3_finalize(addStmt); 

sqlite3_close(database); 
} 

然後我的錯誤看起來是這樣的:

Assertion failure in -[YTOObiectAsigurat addObiectAsigurat] 
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error while inserting data. 'database is locked'' 
*** First throw call stack: 
(0x1ba3012 0x16fae7e 0x1ba2e78 0x1190665 0xb6661 0x3d534 0x63a82 0x1200589 0x11fe652 0x11ff89a 0x11fe60d 0x11fe785 0x114ba68 0x2696911 0x2695bb3 0x26d3cda 0x1b458fd 0x26d435c 0x26d42d5 0x25be250 0x1b26f3f 0x1b2696f 0x1b49734 0x1b48f44 0x1b48e1b 0x1ad27e3 0x1ad2668 0x63effc 0xf4d5 0x2615) 
libc++abi.dylib: terminate called throwing an exception 

如果我使用這個


sqlite3_finalize(addStmt); 
    } 
sqlite3_close(database); 
} 

我變得糟糕線程1:

EXC_BAD_ACCESS 

libsqlite3.dylib`sqlite3_finalize: 
0x37fce0: pushl %ebp 
0x37fce1: movl %esp, %ebp 
0x37fce3: pushl %ebx 
0x37fce4: pushl %edi 
0x37fce5: pushl %esi 
0x37fce6: subl $28, %esp 
0x37fce9: calll 0x37fcee     ; sqlite3_finalize + 14 
0x37fcee: popl %eax 
0x37fcef: movl %eax, -16(%ebp) 
0x37fcf2: xorl %edi, %edi 
0x37fcf4: movl 8(%ebp), %esi 
0x37fcf7: testl %esi, %esi 
0x37fcf9: je  0x37fe16     ; sqlite3_finalize + 310 
0x37fcff: movl (%esi), %ebx 
0x37fd01: testl %ebx, %ebx 
0x37fd03: je  0x37fd1f     ; sqlite3_finalize + 63 
0x37fd05: cmpl $2687084183, 60(%ebx) 
0x37fd0c: jne 0x37fd1f     ; sqlite3_finalize + 63 
0x37fd0e: movl 48(%esi), %eax 
0x37fd11: cmpl $3186757027, %eax 
0x37fd16: je  0x37fd6a     ; sqlite3_finalize + 138 
0x37fd18: cmpl $1369188723, %eax 
0x37fd1d: je  0x37fd6a     ; sqlite3_finalize + 138 
0x37fd1f: movl -16(%ebp), %esi 
0x37fd22: leal 726721(%esi), %eax 
0x37fd28: movl %eax, 4(%esp) 
0x37fd2c: movl $21, (%esp) 
0x37fd33: calll 0x37b7c0     ; sqlite3_log 
0x37fd38: leal 705186(%esi), %eax 
0x37fd3e: movl %eax, 12(%esp) 
0x37fd42: leal 705450(%esi), %eax 
0x37fd48: movl %eax, 4(%esp) 
0x37fd4c: movl $67126, 8(%esp) 
0x37fd54: movl $21, (%esp) 
0x37fd5b: calll 0x37b7c0     ; sqlite3_log 
0x37fd60: movl $21, %edi 
0x37fd65: jmp 0x37fe16     ; sqlite3_finalize + 310 
0x37fd6a: movl 12(%ebx), %edi 
0x37fd6d: testl %edi, %edi 
0x37fd6f: je  0x37fd80     ; sqlite3_finalize + 160 
0x37fd71: movl %edi, (%esp) 
0x37fd74: movl -16(%ebp), %eax 
0x37fd77: calll *759034(%eax) 
0x37fd7d: movl 48(%esi), %eax 
0x37fd80: movl %edi, -20(%ebp) 
0x37fd83: cmpl $3186757027, %eax 
0x37fd88: je  0x37fd93     ; sqlite3_finalize + 179 
0x37fd8a: xorl %edi, %edi 
0x37fd8c: cmpl $1369188723, %eax 
0x37fd91: jne 0x37fd9c     ; sqlite3_finalize + 188 
0x37fd93: movl %esi, %ecx 
0x37fd95: calll 0x37ff00     ; sqlite3VdbeReset 
0x37fd9a: movl %eax, %edi 
0x37fd9c: movl 60(%esi), %eax 
0x37fd9f: movl (%esi), %ecx 
0x37fda1: movl 56(%esi), %edx 
0x37fda4: testl %edx, %edx 
0x37fda6: je  0x37fdad     ; sqlite3_finalize + 205 
0x37fda8: movl %eax, 60(%edx) 
0x37fdab: jmp 0x37fdb0     ; sqlite3_finalize + 208 
0x37fdad: movl %eax, 4(%ecx) 
0x37fdb0: movl 60(%esi), %eax 
0x37fdb3: testl %eax, %eax 
0x37fdb5: je  0x37fdbd     ; sqlite3_finalize + 221 
0x37fdb7: movl 56(%esi), %edx 
0x37fdba: movl %edx, 56(%eax) 
0x37fdbd: movl $3053896648, 48(%esi) 
0x37fdc4: movl $0, (%esi) 
0x37fdca: movl %esi, %edx 
0x37fdcc: calll 0x378cd0     ; sqlite3VdbeDeleteObject 
0x37fdd1: cmpb $0, 50(%ebx) 
0x37fdd5: jne 0x37fddf     ; sqlite3_finalize + 255 
0x37fdd7: cmpl $3082, %edi 
0x37fddd: jne 0x37fe00     ; sqlite3_finalize + 288 
0x37fddf: movl %ebx, (%esp) 
0x37fde2: movl $0, 8(%esp) 
0x37fdea: movl $7, 4(%esp) 
0x37fdf2: calll 0x37d090     ; sqlite3Error 
0x37fdf7: movb $0, 50(%ebx) 
0x37fdfb: movl $7, %edi 
0x37fe00: andl 44(%ebx), %edi 
0x37fe03: movl -20(%ebp), %eax 
0x37fe06: testl %eax, %eax 
0x37fe08: je  0x37fe16     ; sqlite3_finalize + 310 
0x37fe0a: movl %eax, (%esp) 
0x37fe0d: movl -16(%ebp), %eax 
0x37fe10: calll *759042(%eax) 
0x37fe16: movl %edi, %eax 
0x37fe18: addl $28, %esp 
0x37fe1b: popl %esi 
0x37fe1c: popl %edi 
0x37fe1d: popl %ebx 
0x37fe1e: popl %ebp 
0x37fe1f: ret  

這些都是我的插入,更新所有方法,刪除和選擇。

- (void) addObiectAsigurat 
{ 
sqlite3 *database = nil; 
sqlite3_stmt *addStmt = nil; 

if(sqlite3_open([[Database getDBPath] UTF8String], &database) == SQLITE_OK) 
{ 

    if(addStmt == nil) { 
     const char *sql = "INSERT INTO ObiectAsigurat (IdIntern, TipObiect, JSONText) Values(?, ?, ?)"; 
     if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK) 
      NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database)); 
    } 

    sqlite3_bind_text(addStmt, 1, [IdIntern UTF8String], -1, SQLITE_TRANSIENT); 
    sqlite3_bind_int(addStmt, 2, TipObiect); 
    sqlite3_bind_text(addStmt, 3, [JSONText UTF8String], -1, SQLITE_TRANSIENT); 


    if(SQLITE_DONE != sqlite3_step(addStmt)) 
     NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database)); 
    else { 
     sqlite3_finalize(addStmt); 
     sqlite3_close(database); 
    } 

     sqlite3_finalize(addStmt); 
} 
sqlite3_close(database); 
} 

- (void) updateObiectAsigurat 
{ 
sqlite3 *database = nil; 
sqlite3_stmt *updateStmt = nil; 

if(sqlite3_open([[Database getDBPath] UTF8String], &database) == SQLITE_OK) 
{ 

    if(updateStmt == nil) { 
     NSString *update = [NSString stringWithFormat:@"UPDATE ObiectAsigurat SET JSONText = ? WHERE IdIntern='%@'", IdIntern]; 

     if(sqlite3_prepare_v2(database, [update UTF8String], -1, &updateStmt, NULL) != SQLITE_OK) 
      NSAssert1(0, @"Error while creating update statement. '%s'", sqlite3_errmsg(database)); 
    } 

    sqlite3_bind_text(updateStmt, 1, [JSONText UTF8String], -1, SQLITE_TRANSIENT);      

    if(SQLITE_DONE != sqlite3_step(updateStmt)) 
     NSAssert1(0, @"Error while updating data. '%s'", sqlite3_errmsg(database)); 
    else { 
     sqlite3_finalize(updateStmt); 
     sqlite3_close(database); 
    } 
    sqlite3_finalize(updateStmt); 
} 


sqlite3_close(database); 
} 

- (void) deleteObiectAsigurat 
{ 
sqlite3 *database = nil; 
sqlite3_stmt *deleteStmt = nil; 

if(sqlite3_open([[Database getDBPath] UTF8String], &database) == SQLITE_OK) 
{ 

    if(deleteStmt == nil) { 
     NSString *delete = [NSString stringWithFormat:@"DELETE FROM ObiectAsigurat WHERE IdIntern='%@'", IdIntern]; 

     if(sqlite3_prepare_v2(database, [delete UTF8String], -1, &deleteStmt, NULL) != SQLITE_OK) 
      NSAssert1(0, @"Error while creating delete statement. '%s'", sqlite3_errmsg(database)); 
    } 

    if(SQLITE_DONE != sqlite3_step(deleteStmt)) 
     NSAssert1(0, @"Error while deleting data. '%s'", sqlite3_errmsg(database)); 
    else { 
     sqlite3_finalize(deleteStmt); 
     sqlite3_close(database); 
    } 
    sqlite3_finalize(deleteStmt); 
} 

sqlite3_close(database); 
} 

+ (YTOObiectAsigurat *) getObiectAsigurat:(NSString *)idIntern 
{ 
YTOObiectAsigurat * ob = [[YTOObiectAsigurat alloc] init]; 
sqlite3 *database; 
sqlite3_stmt *selectstmt = nil; 

if (sqlite3_open([[Database getDBPath] UTF8String], &database) == SQLITE_OK) { 
    NSString * sqlstring = [NSString stringWithFormat:@"SELECT IdIntern, TipObiect, JSONText FROM ObiectAsigurat WHERE IdIntern='%@'", idIntern]; 
    const char *sql = [sqlstring UTF8String]; 

    if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { 

     while(sqlite3_step(selectstmt) == SQLITE_ROW) { 
      ob._isDirty = YES; 

      ob.IdIntern = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)]; 
      ob.TipObiect = sqlite3_column_int(selectstmt, 1); 
      ob.JSONText = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)]; 
     } 
    } 
    sqlite3_finalize(selectstmt); 
} 

sqlite3_close(database); 

return ob; 
} 

+ (NSMutableArray *) getListaByTipObiect:(int)tip; 
{ 
NSMutableArray * _list = [[NSMutableArray alloc] init]; 
sqlite3 *database; 
sqlite3_stmt *selectstmt = nil; 

if (sqlite3_open([[Database getDBPath] UTF8String], &database) == SQLITE_OK) { 
    NSString * sqlstring = [NSString stringWithFormat:@"SELECT IdIntern, TipObiect, JSONText FROM ObiectAsigurat WHERE TipObiect=%d",tip]; 
    const char *sql = [sqlstring UTF8String]; 

    if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { 

     while(sqlite3_step(selectstmt) == SQLITE_ROW) { 

      YTOObiectAsigurat * ob = [[YTOObiectAsigurat alloc] init]; 
      ob._isDirty = YES; 

      ob.IdIntern = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)]; 
      ob.TipObiect = sqlite3_column_int(selectstmt, 1); 
      ob.JSONText = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)]; 

      [_list addObject:ob]; 
     } 
    } 
    sqlite3_finalize(selectstmt); 
} 

sqlite3_close(database); 

return _list; 
} 

@end 

編輯:我解決了我的問題很容易。

我沒有最終確定和關閉插入,更新,刪除的方法中的數據庫,我只是重置語句,然後使其爲零。在此之後,我宣佈一個方法finalize,在那裏我關閉數據庫並最終確定語句。也許這個想法會幫助某人。

+0

,請複製粘貼UR錯誤 – 2013-02-20 08:34:43

+0

你在一個循環中調用-addObiectAsigurat? – Oleg 2013-02-20 08:53:54

+0

@Oleg是的。在for循環中。我想從nsdictionary中插入對象。 – 2013-02-20 09:03:08

回答

1
  1. 確保您在使用它的其他方法中關閉數據庫連接。

  2. 既然你打電話給你的方法在一個循環中,有更有效的方式與數據庫的工作,當你需要數據的批量插入: 通過你的價值觀重建您的應用程序循環內INSERT這樣的: 這只是舉例來說,在這裏插入正確的價值觀

    -(void)insertValuesFromArray:(NSMutableArray *)array { 
    
    sqlite3 * database; 
    
    const char *dbpath = [[Database getDBPath] UTF8String]; 
    
    if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
    { 
        sqlite3_exec(database, "BEGIN TRANSACTION", 0, 0, 0); 
        const char *sqlStatement = "INSERT INTO ObiectAsigurat (IdIntern) Values(?)"; 
        sqlite3_stmt *compiledStatement; 
    
        if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { 
         int hasError = 0; 
    
         for (int i=0; i<[array count]; i++) { 
          sqlite3_bind_text(compiledStatement, 1, [[array objectAtIndex:i] UTF8String], -1, SQLITE_TRANSIENT); 
    
    
          if (sqlite3_step(compiledStatement) != SQLITE_DONE) { 
           hasError=1; 
           NSLog(@"Prepare-error %s", sqlite3_errmsg(database)); 
          } 
    
          sqlite3_reset(compiledStatement); 
         } 
    
         sqlite3_finalize(compiledStatement); 
    
         if(hasError == 0) { 
          sqlite3_exec(database, "COMMIT", 0, 0, 0); 
          NSLog(@"inserted successfully"); 
         } 
         else { 
          sqlite3_exec(contactDB, "ROLLBACK", 0, 0, 0); 
          NSLog(@"can't insert:"); 
         } 
        } 
        sqlite3_close(contactDB); 
    } 
    
    } 
    
+0

謝謝你的回答。我會嘗試你的方式。 :) – 2013-02-20 09:25:45

0

一種可能性是,你是不是犯插入事務。搜索如何提交併嘗試一些解決方案。

以下可幫助

SQLite 3 C API Transactions

忽略,如果你已經嘗試過....

+0

他正在做一個INSERT,沒有TRANSACTIONs所以沒有必要使用COMMIT那裏:-) – Oleg 2013-02-20 08:53:20