我正在尝试在 Swift 中创建一个简单的 sqlite 数据库,但在尝试创建表时遇到错误(特别是 SQLITE_ERROR)。
这是我的代码:
var db :OpaquePointer?
let dbPath = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("\(Date.init().timeIntervalSince1970)".replacingOccurrences(of: ".", with: "") + ".db")
.absoluteString
var returnCode :Int32 = sqlite3_open(dbPath.cString(using: .utf8), &db)
if SQLITE_OK != returnCode {
preconditionFailure("Failed to open db")
}
var stmt :OpaquePointer?
returnCode = sqlite3_prepare_v2(db, "CREATE TABLE Things (name TEXT)".cString(using: .utf8), -1, &stmt, nil)
if SQLITE_OK != returnCode {
preconditionFailure("Failed to prepare table creation SQL")
}
Sqlite 是通过 Cocoapod 包含的。在转换为 C 字符串时,我尝试过使用不同的字符串编码,特别是我尝试过使用 ASCII 编码,并且我还尝试过对数据库名称进行硬编码。
错误发生在sqlite3_prepare_v2
中。
错误消息为“near\”\u{01}\”:语法错误”
最佳答案
我不是 100% 确定为什么你的 .cString(using: .utf8)
方法
将 Swift 字符串转换为 C 字符串会导致问题。
这可能是与以下相同的问题
Why does Swift return an unexpected pointer when converting an optional String into an UnsafePointer? (这是
报告为 Swift bug)。解开 cString()
的结果
明确似乎有帮助:
let sql = "CREATE TABLE Things (name TEXT)".cString(using: .utf8)!
returnCode = sqlite3_prepare_v2(db, sql, -1, &stmt, nil)
但是你可以将 Swift String
直接传递给期望的 C 函数
a const char *
(比较 String value to UnsafePointer<UInt8> function parameter behavior ):
var returnCode = sqlite3_open(dbPath, &db)
// ...
returnCode = sqlite3_prepare_v2(db, "CREATE TABLE Things (name TEXT)", -1, &stmt, nil)
这按预期工作。
补充说明:
- 使用
.path
将URL
转换为文件路径字符串, 不是.absoluteString
。 - 如果出现问题,请使用
sqlite3_errmsg()
获取错误消息。 - 删除不必要的类型注释,如
var returnCode :Int32
。
把它们放在一起:
var db: OpaquePointer?
let dbPath = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("xxx.db")
.path
var returnCode = sqlite3_open(dbPath, &db)
if SQLITE_OK != returnCode {
let errmsg = String(cString: sqlite3_errmsg(db))
fatalError("Failed to open db: \(errmsg)")
}
var stmt: OpaquePointer?
returnCode = sqlite3_prepare_v2(db, "CREATE TABLE Things (name TEXT)", -1, &stmt, nil)
if SQLITE_OK != returnCode {
let errmsg = String(cString: sqlite3_errmsg(db))
fatalError("Failed to prepare table creation SQL: \(errmsg)")
}
关于Swift Sqlite SQL 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40888684/