我正在使用“原始”C 函数访问我的 SQLite 数据库,并在日期和文本字段方面遇到 2 个问题,我的代码,考虑到一切都已经在工作了:
let queryString = "INSERT INTO LOG (field1, field2, field3, field4) VALUES (?, ?, ?, ?);"
if sqlitePrepare(database: &db, query: queryString, statement: &insertStatement) == SQLITE_OK {
sqlite3_bind_int(insertStatement, 1, intVar)
sqlite3_bind_double(insertStatement, 2, Date().timeIntervalSinceReferenceDate)
sqlite3_bind_text(insertStatement, 3, strVar1, -1, nil)
sqlite3_bind_text(insertStatement, 4, strVar2, -1, nil)
if sqlite3_step(insertStatement) != SQLITE_DONE {
let errmsg = String(cString: sqlite3_errmsg(db)!)
print("failure insert: \(errmsg)")
}
sqlite3_finalize(insertStatement)
}
问题 #1 是如何将日期字段填充为有效的 SQLite 时间戳? 问题 #2 和更重要的是,使用字符串字段 (field3/field4) 更新到表中的值是错误的。只有最后一个值用于填充两者 (strVar1/strVar2),因此如果 strVar1 = "A"和 strVar2 = "B",则 field3 和 field4 都保存为 "B",即 strVar2 的值。 这很奇怪,因为我发现的所有示例在这里都没有区别。
最佳答案
#1 是如何将 Date 字段填充为有效的 SQLite 时间戳?
SQLite3 没有 DATETIME 类型也没有 TIMESTAMP 类型。因此,您需要将时间戳存储为文本或数字。
选择NUMERIC时,最好使用UNIX纪元时间。
sqlite3_bind_double(insertStatement, 2, Date().timeIntervalSince1970)
#2
当将字符串传递给 UnsafePointer<Int8>
类型的参数时,Swift 会分配一个临时区域来存储 UTF-8 表示形式.并且该区域在函数调用后立即释放,并可能被重复使用。
试试这个:
sqlite3_bind_text(insertStatement, 3, strdup(strVar1), -1, free)
sqlite3_bind_text(insertStatement, 4, strdup(strVar2), -1, free)
strdup
分配一个稳定的区域,该区域在 free
之前可用d.
或者(感谢 rmaddy 和 Martin R "SQLITE_TRANSIENT undefined in Swift" ),你可以使用 SQLITE_TRANSIENT
.
在代码的某处定义:
let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)
并使用它:
sqlite3_bind_text(insertStatement, 3, strVar1, -1, SQLITE_TRANSIENT)
sqlite3_bind_text(insertStatement, 4, strVar2, -1, SQLITE_TRANSIENT)
关于插入时 Swift 4 + SQLite,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52544093/