我想创建一个函数,该函数执行sqlite3_exec
并将结果保存到作为参数传递的字典对象中。为此,我创建了以下代码:
func execute(sql: String, result: inout Dictionary<String, String>) {
let rc = sqlite3_exec(
dbPointer, // database
sql, // statement
{ // callback: non-capturing closure
resultVoidPointer, columnCount, values, columns in
for i in 0 ..< Int(columnCount) {
let value = String(cString: values![i]!)
let column = String(cString: columns![i]!)
result[column] = value // Error: Escaping closures can only capture inout parameters explicitly by value
print("\(column) = \(value)")
}
return 0
},
nil,
nil
)
if rc != SQLITE_OK {
print("SQLite Error: " + errorMessage)
}
}
但是此代码给了我以下错误:Escaping closures can only capture inout parameters explicitly by value
。另一个尝试是使函数execute
返回字典对象,但是错误消息变为:A C function pointer cannot be formed from a closure that captures context
。我该如何解决?
答案 0 :(得分:0)
在Shawn的评论之后,我创建了execute
的新版本,在这里我使用sqlite3_prepare_v2
,sqlite3_step
和sqlite3_finalize
而不是组合函数sqlite3_exec
:
func prepare(sql: String) -> OpaquePointer? {
var statement: OpaquePointer? = nil
guard sqlite3_prepare_v2(dbPointer, sql, -1, &statement, nil) == SQLITE_OK else {
print(errorMessage)
return nil
}
return statement
}
func execute(sql: String) -> [Dictionary<String, String>] {
var result: [Dictionary<String, String>] = []
guard let queryStatement = prepare(sql: sql) else {
return result
}
defer {
sqlite3_finalize(queryStatement)
}
while sqlite3_step(queryStatement) == SQLITE_ROW {
var dictionary: Dictionary<String, String> = [:]
for i in 0...sqlite3_column_count(queryStatement)-1 {
let column: String = String(cString: sqlite3_column_name(queryStatement, i))
let value: String = String(cString: sqlite3_column_text(queryStatement, i))
dictionary[column] = value
}
result.append(dictionary)
}
guard sqlite3_step(queryStatement) == SQLITE_DONE else {
print(errorMessage)
return result
}
return result
}
我的execute
函数现在返回一个字典数组,其中每个字典代表SQL语句(如SELECT)的一行。对于诸如INSERT,UPDATE或DELETE之类的其他SQL语句,其中将不返回任何行,该函数execute
返回一个空数组。
执行SQL语句后,可以通过
访问结果let result = execute(db, "SELECT id, name, age FROM Table")
print(result[i][age]) // prints the value in row i and column age