为什么这只插入数组中的第一个值?

Why is this only inserting the first values from the array?

我正在尝试插入存储在 NSMutableArray 中的数据并将其存储在 SQLite 数据库中。到目前为止,我只能插入数组的前 5 个元素或将它们全部插入第一列数据库的。我不知道它在哪里 breaking/not 工作。

lockInfo (NSMutableArray) 的内容:

LOCKINFO (
    51974,
    0,
    2,
    15,
    1,
    51975,
    0,
    24,
    15,
    1,
    51976,
    0,
    20,
    15,
    1,
    51977,
    0,
    23,
    15,
    1
    )

插入第一行的所有内容是:

51974,
    0,
    2,
    15,
    1

代码:

-(void)insertLock:(NSMutableArray *)lockInfo{
    char *error;
    NSString *databasePath = [self dataPath:@"eloqdb.sqlite3"];
    sqlite3 *database;
    if (sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSLog(@"Could not open database");
    }else{
        NSLog(@"DB opened");
    }

    //for each element in the array, save the array index, and the contact:

     NSLog(@"count %@", lockInfo);

    NSLog(@"count %i", lockInfo.count);

    for (int i = 0; i < lockInfo.count; i++) {


        sqlite3_stmt *statement;
        NSString *SQLInsert = @"INSERT OR REPLACE INTO LOCK_PLAN_CHANGE (ID, FLAG, ITEM_DOOR_ID, KEY_SERIAL, TIMEZONE_ITEM_ID) "
        @"VALUES (?, ?, ?, ?, ?);";
        if (sqlite3_prepare_v2(database, [SQLInsert UTF8String], -1,
                               &statement, nil) == SQLITE_OK)
        {
            sqlite3_bind_text(statement, 1, [[lockInfo objectAtIndex:i] UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 2, [[lockInfo objectAtIndex:i] UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 3, [[lockInfo objectAtIndex:i] UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 4, [[lockInfo objectAtIndex:3] UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 5, [[lockInfo objectAtIndex:4] UTF8String], -1, NULL);
        }
        if (sqlite3_step(statement) != SQLITE_DONE) {
            // NSAssert1(0, @"Cannot Update Table", error);
        }
        sqlite3_finalize(statement);
    }
    sqlite3_close(database);
}

您的数组实际上包含 lockInfo.count / 5 行数据。

将循环更改为:

for (int i = 0; i < lockInfo.count; i += 5) {

然后将绑定更新为:

sqlite3_bind_text(statement, 1, [[lockInfo objectAtIndex:i] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 2, [[lockInfo objectAtIndex:i+1] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 3, [[lockInfo objectAtIndex:i+2] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 4, [[lockInfo objectAtIndex:i+3] UTF8String], -1, NULL);
sqlite3_bind_text(statement, 5, [[lockInfo objectAtIndex:i+4] UTF8String], -1, NULL);

这些更改会将正确的值放入正确的列中,并且会添加正确的行数。

顺便说一句 - 这是一个非常糟糕的数据结构。您应该定义一个 class 或具有 5 个属性的结构。然后有一个 class 或 struct.

的数组

除了这个主要问题之外,您也没有正确使用准备好的语句。您应该在循环之前只准备一次语句。

这是您正确编写的代码,同时还进行了更好的错误检查:

- (void)insertLock:(NSMutableArray *)lockInfo {
    NSString *databasePath = [self dataPath:@"eloqdb.sqlite3"];
    sqlite3 *database;
    if (sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK) {
        NSLog(@"Could not open database");
        return;
    } else {
        NSLog(@"DB opened");
    }

    //for each element in the array, save the array index, and the contact:

    NSLog(@"lockInfo %@", lockInfo);
    NSLog(@"count %i", lockInfo.count);

    sqlite3_stmt *statement;
    NSString *SQLInsert = @"INSERT OR REPLACE INTO LOCK_PLAN_CHANGE (ID, FLAG, ITEM_DOOR_ID, KEY_SERIAL, TIMEZONE_ITEM_ID) VALUES (?, ?, ?, ?, ?);";
    if (sqlite3_prepare_v2(database, [SQLInsert UTF8String], -1, &statement, nil) == SQLITE_OK) {
        for (NSInteger i = 0; i < lockInfo.count; i += 5) {
            sqlite3_bind_text(statement, 1, [lockInfo[i] UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 2, [lockInfo[i+1] UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 3, [lockInfo[i+2] UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 4, [lockInfo[i+3] UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 5, [lockInfo[i+4] UTF8String], -1, NULL);

            if (sqlite3_step(statement) != SQLITE_DONE) {
                // NSAssert1(0, @"Cannot Update Table", error);
            }
            sqlite3_reset(statement);
        }
        sqlite3_finalize(statement);
    } else {
        NSLog(@"Can't prepare: %s", sqlite3_errmsg(database));
    }
    sqlite3_close(database);
}