2013-07-02 2 views
0

Après trois jours d'essai, je suis venu ici pour obtenir de l'aide. Je souhaite mettre à jour plusieurs colonnes dans ma base de données SQLite dans mon application. Donc, j'ai un "pour" appeler la méthode de mise à jour plusieurs fois que nécessaire. Mais seule la première rangée est affectée.iOS Mise à jour SQLite numéro

Ma boucle ressemble:

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"]]; 
     } 

Et ma méthode de mise à jour est la suivante:

- (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; 
}  
} 

La méthode génère pas d'erreur, il est dit que tout est normal et mises à jour a été exécuté. Mais quand je fais un SELECT * à cette table, seule la première rangée a été affectée. S'il vous plaît, s'il vous plaît, jetez un oeil au code et dites-moi ce qui ne va pas.

MERCI!

Répondre

0

Je vois que vous fermez votre base de données à la fin de la fonction updateColumns. Je ne vois pas que vous l'ouvriez jamais. Si vous faites beaucoup de requêtes dans cette boucle, vous pouvez ouvrir avant la boucle et fermer après quelque chose comme ça.

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

Même problème ... Il dit que la mise à jour a été exécuté parfaitement, mais quand je fais la sélection, seule la première ligne a été modifiée –

+0

En supposant que vous avez retiré sqlite3_close (base de données); à partir de updateColumns et vous êtes sqlite3_finalize (instruction); après chaque préparation sqlite3_prepare_v2 (base de données, sql, -1, & déclaration, NULL). Je voudrais juste mettre quelques déclarations de journal ou passer par le code pour s'assurer qu'il est en train d'exécuter l'instruction autant que prévu. –