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

问题描述 投票:0回答:1

我正在尝试插入存储在NSMutableArray中的数据并将其存储在SQLite数据库中。到目前为止,我只能插入数组的前5个元素或将它们全部插入到DB的第一列中。我无法弄清楚它在哪里破碎/不起作用。

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);
}
objective-c sqlite nsmutablearray
1个回答
1
投票

您的数组实际上包含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);

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

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

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

这是您正确编写的代码,以及更好的错误检查:

- (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);
}
© www.soinside.com 2019 - 2024. All rights reserved.