2013-07-02 79 views
0

經過三天的努力,我來到這裏得到了som的幫助。 我想更新我的應用程序中的SQLite數據庫中的多個列。 所以我有一個「for」根據需要多次調用更新方法。但只有第一行受到影響。iOS SQLite更新問題

我的for循環看起來像:

for (NSDictionary *friend in friends) 
     { 
      NSMutableArray *valuesForUpdate = [[NSMutableArray alloc] init]; 
      DBHelper *dbHelper = [[DBHelper alloc] initWithPath:@"DB_CodiUp"]; 
      [valuesForUpdate addObject:[friend objectForKey:@"name"]]; 
      [valuesForUpdate addObject:[friend objectForKey:@"code"]]; 
      [valuesForUpdate addObject:[friend objectForKey:@"store"]]; 
      [valuesForUpdate addObject:[friend objectForKey:@"imgData"]]; 
      [dbHelper updateColumns:columnsToUpdate inTable:tableName withValues:valuesForUpdate where:@"id" isIqualsTo:[friend objectForKey:@"id"]]; 
     } 

而且我的更新方法是這樣的:

- (BOOL) updateColumns:(NSArray *)columns inTable:(NSString *)tableName withValues:(NSArray *)values where:(NSString *)columnSelector isIqualsTo:(NSString *)selector 
{ 
sqlite3_stmt *statement; 
const char *sql; 
NSString *preSQL = [NSString stringWithFormat:@"Update %@ set ",tableName]; 

//Build sql 
for(int i = 0; i < [columns count]; i++){ 
    if(i == 0) 
     preSQL = [NSString stringWithFormat:@"%@ %@ = ?", preSQL,[columns objectAtIndex:i]]; 
    else 
     preSQL = [NSString stringWithFormat:@"%@ , %@ = ?", preSQL,[columns objectAtIndex:i]]; 
} 
preSQL = [NSString stringWithFormat:@"%@ where %@ = %@", preSQL, columnSelector, selector]; 
sql = [preSQL UTF8String]; 

//Prepare statement 
if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) 
{ 

    for(int i = 0; i < [values count]; i++){ 
     if([[values objectAtIndex:i] isKindOfClass:[NSString class]]) 
     { 
      sqlite3_bind_text(statement,i+1,[[values objectAtIndex:i] UTF8String], -1, SQLITE_TRANSIENT); 
     } 
     else if([[values objectAtIndex:i] isKindOfClass:[NSNumber class]]) 
     { 
      sqlite3_bind_int(statement, i+1, ((NSNumber *)[values objectAtIndex:i]).integerValue); 
     } 
     else if ([[values objectAtIndex:i] isKindOfClass:[NSData class]]) 
     { 
      sqlite3_bind_blob(statement, i+1, [[values objectAtIndex:i] bytes], [[values objectAtIndex:i] length], SQLITE_TRANSIENT); 
     } 
     else 
     { 
      NSLog(@"[SQLITE UPDATE] ERROR! The value at index %d is not a recognized data type", i); 
     } 
    } 

    //Execute statement 
    int success; 
    success = sqlite3_step(statement); 
    if (success != SQLITE_DONE) 
    { 
     NSLog(@"Error on step: %i",sqlite3_errcode(database)); 
    } 

    sqlite3_finalize(statement); 
    NSLog(@"[DataBase]Updated row"); 
    sqlite3_close(database); 
    return YES; 
} 
else 
{ 
    NSAssert1(0,@"Error: Failed to prepare statement with message %s '.", sqlite3_errmsg(database)); 
    return NO; 
}  
} 

的方法拋出任何錯誤,它說一切正常,並更新已執行。但是當我對該表執行SELECT *時,只有第一行受到了影響。 請仔細看看代碼,告訴我做錯了什麼。

謝謝!

回答

0

我看到你正在updateColumns函數的末尾關閉你的數據庫。我看不到你曾經打開過它。如果你在這個循環中做了很多的查詢,你可能想在循環之前打開並關閉類似的東西。

if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK){ 
    sqlite3_exec(database, "BEGIN EXCLUSIVE TRANSACTION", 0, 0, 0); 
    for (NSDictionary *friend in friends) { 
     //perform update query 
    } 
    sqlite3_exec(database, "COMMIT TRANSACTION", 0, 0, 0); 
    sqlite3_close(database); 
} 
+0

同樣的問題...它說,該更新已經完全執行,但是當我做了選擇,只有第一行已經改變 –

+0

假設你刪除sqlite3_close(數據庫);來自updateColumns,你是sqlite3_finalize(語句);在每次準備sqlite3_prepare_v2(數據庫,sql,-1,&語句,NULL)之後。我只會放一些日誌語句或逐句通過代碼,以確保它實際上按照預期執行語句。 –