Swift SQLite写入单行多字段仅最后值覆盖所有单元格的修复方法
解决SQLite插入时所有字段被最后一个值覆盖的问题
这个问题我太熟了!大概率是你在绑定SQLite参数的时候,所有字段都用了同一个索引编号,导致后面的值把前面的全覆盖了😉
核心原因
SQLite的占位符?是按从1开始的顺序对应参数索引的,你的INSERT语句里有7个?,分别对应title到privacyRequest这7个字段。如果所有sqlite3_bind_text调用都用了同一个索引(比如全写1),那最后一次绑定的值会覆盖所有位置,自然所有单元格都是最后那个值。
正确的绑定步骤
你需要给每个字段对应正确的索引,从1到7依次绑定:
//creating a statement var insertStatement: OpaquePointer? = nil //the insert query let queryString = "INSERT INTO Users (title, firstName, lastName, email, affiliatedOrg, region, privacyRequest) VALUES (?,?,?,?,?,?,?);" if sqlite3_prepare_v2(db, queryString, -1, &insertStatement, nil) == SQLITE_OK { // 绑定title到第1个参数 sqlite3_bind_text(insertStatement, 1, title, -1, SQLITE_TRANSIENT) // 绑定firstName到第2个参数 sqlite3_bind_text(insertStatement, 2, firstName, -1, SQLITE_TRANSIENT) // 绑定lastName到第3个参数 sqlite3_bind_text(insertStatement, 3, lastName, -1, SQLITE_TRANSIENT) // 绑定email到第4个参数 sqlite3_bind_text(insertStatement, 4, email, -1, SQLITE_TRANSIENT) // 绑定affiliatedOrg到第5个参数 sqlite3_bind_text(insertStatement, 5, affiliatedOrg, -1, SQLITE_TRANSIENT) // 绑定region到第6个参数 sqlite3_bind_text(insertStatement, 6, region, -1, SQLITE_TRANSIENT) // 绑定privacyRequest到第7个参数 sqlite3_bind_text(insertStatement, 7, privacyRequest, -1, SQLITE_TRANSIENT) // 执行插入操作 if sqlite3_step(insertStatement) == SQLITE_DONE { print("用户数据插入成功!") } else { let errorMsg = String(cString: sqlite3_errmsg(db)) print("插入失败:\(errorMsg)") } // 重置语句(如果需要重复插入)或者释放资源 sqlite3_reset(insertStatement) } else { let errorMsg = String(cString: sqlite3_errmsg(db)) print("预处理语句失败:\(errorMsg)") } // 不再使用语句时记得释放 sqlite3_finalize(insertStatement)
额外注意事项
- 如果某个字段不是字符串类型(比如
region是数字),要使用对应的绑定函数,比如sqlite3_bind_int,不要全用sqlite3_bind_text。 SQLITE_TRANSIENT参数是告诉SQLite自行管理传入字符串的内存,避免野指针问题;如果是静态字符串也可以用SQLITE_STATIC。- 每次插入完成后,记得用
sqlite3_reset重置语句(如果要循环插入多条数据),或者用sqlite3_finalize释放资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者user1391152
相关产品推荐
相关产品推荐

