swift - 如何在 Swift 程序中更新 SQLite 表中的列?

标签 swift sqlite

这是我在第一次绑定(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.

参见https://www.sqlite.org/c3ref/finalize.html

关于swift - 如何在 Swift 程序中更新 SQLite 表中的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60979056/

相关文章:

android - SQLite 数据库不会更新,除非我手动卸载然后安装新的 apk

c - SQLite 使用 C 文件添加功能

ios fmdb 从文件加载数据库

android - SQlite 查询按错误的列排序

swift - 如何测试所需的初始化(编码器 :)?

swift - 快速上的图像

ios - 如何在 Xcode/Swift 的 ScrollView 中将多个图像居中

python - 如何将 Python 字典值保存到 SQLite 模型?

ios - 如何使用 Alamofire 和 SwiftyJSON 将 JSON 字典元素中的所有元素附加到数组

ios - 帧速率问题 Apple SpriteKit