Следуя комментариям 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. Для других операторов SQL, таких как INSERT, UPDATE или DELETE, где строки не возвращаются, функция 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