将 FMDB SQLite 结果附加到 Swift 数组
Posted
技术标签:
【中文标题】将 FMDB SQLite 结果附加到 Swift 数组【英文标题】:Append FMDB SQLite results to Swift array 【发布时间】:2015-09-15 05:38:12 【问题描述】:我正在尝试将 FMDB SQLite 查询的结果附加到 Swift 数组。我在 XCode 中遇到的错误是“选项类型“字符串的值?”没有打开。
在while循环中换掉下面这行,FMDB的结果就可以打印到控制台了,所以没有问题。
println(results_lab_test?.stringForColumn("lab_test"))
XCode 新手,请善待...
import UIKit
class ViewController: UIViewController
@IBOutlet weak var tests_label: UILabel!
var databasePath = NSString()
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var arrayData:[String] = []
let filemgr = NSFileManager.defaultManager()
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let docsDir = dirPaths[0] as! String
databasePath = docsDir.stringByAppendingPathComponent("vmd_db.db")
let myDatabase = FMDatabase(path: databasePath as String)
if myDatabase.open()
let query_lab_test = "SELECT lab_test FROM lab_test"
let results_lab_test:FMResultSet? = myDatabase.executeQuery(query_lab_test, withArgumentsInArray: nil)
while results_lab_test?.next() == true
if let resultString = results_lab_test?.stringForColumn("lab_test")
arrayData.append(resultString)
var multiLineString = join("\n", arrayData)
tests_label.text = multiLineString
tests_label.numberOfLines = 0
tests_label.lineBreakMode = NSLineBreakMode.ByWordWrapping
tests_label.sizeToFit()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
感谢@skypecakes 的工作代码:
import UIKit
class ViewController: UIViewController
@IBOutlet weak var tests_label: UILabel!
var databasePath = NSString()
override func viewDidLoad()
super.viewDidLoad()
let filemgr = NSFileManager.defaultManager()
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let docsDir = dirPaths[0] as! String
databasePath = docsDir.stringByAppendingPathComponent("vmd_db.db")
let myDatabase = FMDatabase(path: databasePath as String)
if myDatabase.open()
var arrayData:[String] = []
let query_lab_test = "SELECT lab_test FROM lab_test"
let results_lab_test:FMResultSet? = myDatabase.executeQuery(query_lab_test, withArgumentsInArray: nil)
while results_lab_test?.next() == true
if let resultString = results_lab_test?.stringForColumn("lab_test")
arrayData.append(resultString)
println(arrayData)
myDatabase.close()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
【问题讨论】:
【参考方案1】:好像
results_lab_test?.stringForColumn("lab_test")
返回一个字符串?,这是一个可选的。您的数组被定义为“字符串”项的数组,因此您不能放置“字符串?”在里面。
试试这个:
if let resultString = results_lab_test?.stringForColumn("lab_test")
arrayData.append(resultString)
请注意,通常最好用“if let”解开所有选项,而不是假设它们已被填充。因此,在任何有问号的地方(例如 results_lab_test?.stringForColumn),都可以使用“if let”。
如果您将 XCode 7 与 Swift 2.0 一起使用,这将是“guard let”语句的一个很好的例子,它提供了一种方便的语法来在可选返回 null 时中止您的代码:
guard let queryResults = results_lab_test else return
while queryResults.next() == true
if let resultString = queryResults.stringForColumn("lab_test")
arrayData.append(resultString)
这个测试对我有用(表有 2 行,打印数组会打印 2 行),以防它对您有所帮助:
import UIKit
import FMDB
class ViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
if let myDatabase = makeSqlDB()
var arrayData:[String] = []
let query_lab_test = "SELECT lab_test FROM lab_test"
let results_lab_test:FMResultSet? = myDatabase.executeQuery(query_lab_test, withArgumentsInArray: nil)
while results_lab_test?.next() == true
if let resultString = results_lab_test?.stringForColumn("lab_test")
arrayData.append(resultString)
println(arrayData)
myDatabase.close()
private func makeSqlDB()->FMDatabase?
let database = FMDatabase(path: String())
if !database.open()
println("Unable to open database")
return nil
if !database.executeUpdate("create table lab_test(lab_test text)", withArgumentsInArray: nil)
println("create table failed: \(database.lastErrorMessage())")
if !database.executeUpdate("insert into lab_test (lab_test) values (?)", withArgumentsInArray: ["test1"])
println("insert 1 table failed: \(database.lastErrorMessage())")
if !database.executeUpdate("insert into lab_test (lab_test) values (?)", withArgumentsInArray: ["test2"])
println("insert 2 table failed: \(database.lastErrorMessage())")
return database
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
【讨论】:
谢谢,这会填满数组。但是,我得到与表中记录相同数量的数据集(即 812 组 812 条记录......)。使用 XCode 6.4。 很高兴听到您原来的问题已得到解决。如果您描述预期的行为会有所帮助。您希望结果集中包含什么,以及您希望结果数组包含什么?桌子长什么样?从您的代码看来,有一个名为 lab_test 的表,其中包含一个名为 lab_test 的列,这看起来有点奇怪,但可能会发生。 是的,该列应该称为lab_test_name 或类似名称,但目前它是“lab_test”。表“lab_test”包含 812 条记录。我想将仅使用 lab_test 列的所有记录放入数组中,并最终将它们列在界面小部件的单独行中。 或者,我如何将单独的行上的记录打印到主界面,而不是将结果放入数组中?如果我对结果说 make a label.text =,我只会得到标签中的一行... 你能发布你的整个方法以及调用它的方法吗?听起来循环中可能存在循环。要在单独的行上打印,您需要像使用数组一样遍历结果,并为循环中的每次迭代附加一个换行符和下一个结果。还要确保将标签的 Lines 属性设置为 0。如果您使用自动布局,您可能需要调整它以允许标签增长。以上是关于将 FMDB SQLite 结果附加到 Swift 数组的主要内容,如果未能解决你的问题,请参考以下文章
如何在 IOS Swift 中使用 SQLite 使用 FMDB 处理多个线程