这是我在第一次绑定(bind)时在运行时崩溃的代码:
func update(time: Date) throws {
let sql = "UPDATE Entrys SET date = ? WHERE id = ?" //Questionable
guard let update = try db.prepareStatement(sql: sql) else { throw SQLiteError.prepare }
sqlite3_finalize(update)
let iso8601Time = ISO8601Time(date: time)
guard sqlite3_bind_text(update, 1, iso8601Time.concise(), -1, SQLITE_TRANSIENT) == SQLITE_OK else { throw SQLiteError.bind } //Throws error here
guard sqlite3_bind_int(update, 2, Int32(id)) == SQLITE_OK else { throw SQLiteError.bind }
guard sqlite3_step(update) == SQLITE_ROW else { throw SQLiteError.step }
}
ISO8601Time 是一个在 Text 和 Swift.Date 之间转换的对象,它可以在我插入的其他代码中工作。
文档没有帮助我。
可能是我的 SQL 语法不正确。我在网上没有找到可靠的例子。
请指教。
=)
编辑1:
我已经确认以下代码可以在终端的 sqlite 编辑器中运行。与上面的表格类似
更新条目 SET date = "test"WHERE id = 1;
我还确认我的 sqlite3_bind_text 和 sqlite3_bind_int 在经过单元测试并通过的其他函数中工作。我不确定如何将此语法转移到 UPDATE,并且文档目前还没有我发现的任何内容。
编辑2:
下面显示了插入的 SQLite 语法,该语法有效且具有多个参数,可能有助于解决问题。
func add(date: Date, confirmed: Bool, scale: Int, measurement: SQLMeasurement) throws -> SQLEntry {
let sql = "INSERT INTO Entrys (date, confirmed, scale, measurementID) VALUES (?,?,?,?);"
guard let insert = try? db.prepareStatement(sql: sql) else { fatalError() }
defer { sqlite3_finalize(insert) }
let iso8601Time = ISO8601Time(date: date)
guard sqlite3_bind_text(insert, 1, iso8601Time.concise(), -1, SQLITE_TRANSIENT) == SQLITE_OK else { throw SQLiteError.bind }
var bool: Int //FIXME: Vars are trouble
if confirmed { bool = 1 }
else { bool = 0 }
guard sqlite3_bind_int(insert, 2, Int32(bool)) == SQLITE_OK else { throw SQLiteError.bind }
guard sqlite3_bind_int(insert, 3, Int32(scale)) == SQLITE_OK else { throw SQLiteError.bind }
guard sqlite3_bind_int(insert, 4, Int32(measurement.id)) == SQLITE_OK else { throw SQLiteError.bind }
guard sqlite3_step(insert) == SQLITE_DONE else { throw SQLiteError.step }
let lastId = db.lastId()
return SQLEntry(id: lastId, db: db)
}
最佳答案
正确的顺序是:
- 创建准备好的语句
- 将值绑定(bind)到参数
- 运行 SQL
- 销毁对象以避免资源泄漏(使用
sqlite3_finalize(stmt)
)
您创建了准备好的语句并立即将其删除,但您仍然访问它,这会导致崩溃。
文档:
The sqlite3_finalize() function is called to delete a prepared statement.
关于swift - 如何在 Swift 程序中更新 SQLite 表中的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60979056/