将 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 处理多个线程

iOS Swift 插入 sqlite FMDB

如何在 Swift 中使用“FMDB/SQLCipher”进行加密和解密?

如何通过 FMDB 将数据保存和检索到 sqlite

FMDB/sqlite 查询函数问题

将多个 SQLite 数据库与 FMDB 进行比较