0

3日間試した後、助けを求めてここに来ました。アプリで SQLite データベースの複数の列を更新したいと考えています。そのため、必要に応じて更新メソッドを何度も呼び出す「for」があります。ただし、最初の行のみが影響を受けます。

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

そして、私の Update メソッドは次のとおりです。

- (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 * を実行すると、最初の行だけが影響を受けます。コードを見て、何が間違っているのか教えてください。

ありがとう!

4

1 に答える 1

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);
}
于 2013-07-02T19:52:34.037 に答える