为何NSMutableArray数据插入SQLite仅存首组值?求排查
问题分析与修复方案
我帮你拆解下代码里的核心问题,这就是为啥你只能插入前5个元素、或者数据混乱的原因:
现存问题
- 循环逻辑完全错误:你的
lockInfo是每5个元素对应一条数据库记录(比如51974, 0, 2, 15, 1是第一行,51975, 0, 24, 15, 1是第二行),但你现在的循环是逐个元素遍历,相当于尝试插入20条无效记录,而非4条有效记录。 - 参数绑定索引混乱:你绑定字段时,前三个用了
objectAtIndex:i,第四、第五个直接固定用索引3和4,完全没按每组5个元素的对应关系来,只会重复插入前几个元素的内容。 - 数据类型不匹配:从数组内容看,里面都是数字类型(应该是
NSNumber),但你用了sqlite3_bind_text绑定文本类型,这会导致类型转换错误,数据无法正确存入。 - 错误处理缺失:代码没捕获
sqlite3_prepare_v2和sqlite3_step的错误,出问题时根本不知道哪里错了。
修正后的代码
-(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"); return; // 打开失败直接终止,避免后续无效操作 } NSLog(@"DB opened"); NSLog(@"lockInfo content: %@", lockInfo); NSLog(@"lockInfo count: %i", lockInfo.count); // 每5个元素对应一条记录,循环步长设为5 for (int i = 0; i < lockInfo.count; i += 5) { // 检查剩余元素是否足够组成一条记录,防止数组越界崩溃 if (i + 4 >= lockInfo.count) { NSLog(@"Invalid data: not enough elements at index %d", i); continue; } 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) { NSLog(@"Failed to prepare SQL: %s", sqlite3_errmsg(database)); continue; } // 绑定整数类型参数(假设数组元素是NSNumber) sqlite3_bind_int(statement, 1, [[lockInfo objectAtIndex:i] intValue]); sqlite3_bind_int(statement, 2, [[lockInfo objectAtIndex:i+1] intValue]); sqlite3_bind_int(statement, 3, [[lockInfo objectAtIndex:i+2] intValue]); sqlite3_bind_int(statement, 4, [[lockInfo objectAtIndex:i+3] intValue]); sqlite3_bind_int(statement, 5, [[lockInfo objectAtIndex:i+4] intValue]); if (sqlite3_step(statement) != SQLITE_DONE) { NSLog(@"Failed to execute SQL: %s", sqlite3_errmsg(database)); } sqlite3_finalize(statement); } sqlite3_close(database); }
关键改动说明
- 调整循环步长:把
i++改成i += 5,每次循环处理一组5个元素,对应一条数据库记录。 - 添加越界防护:避免数组元素数量不是5的倍数时,出现越界崩溃。
- 修正绑定索引:每组元素分别对应
i、i+1、i+2、i+3、i+4,和数据库字段一一对应。 - 改用正确的绑定函数:因为数组里是整数,用
sqlite3_bind_int替代sqlite3_bind_text,保证数据类型匹配。 - 完善错误日志:用
sqlite3_errmsg打印具体错误信息,方便后续排查问题。
内容的提问来源于stack exchange,提问作者astric mobiles
相关产品推荐
相关产品推荐

