Search code examples
iosswiftsqlitefmdb

FMDB: NULL Values Are Retrieved as Empty Strings


I'm retrieving a customer record with FMDB and Swift using the (simplified) function below. When the optional value in the title column is NULLthe title member of the returned customer object is an empty string rather than nil, which is misleading. Can this be re-written such that NULL values are retrieved as nil? -- Ideally without testing for empty strings and setting nil explicitly (also wrong if the value is in fact an empty string)?

func getCustomerById(id: NSUUID) -> Customer? {

    let db = FMDatabase(path: dbPath as String)
    if db.open() {
        let queryStatement = "SELECT * FROM Customers WHERE id = ?"
        let result = db.executeQuery(queryStatement, withArgumentsInArray: [id.UUIDString])

        while result.next() {
            var customer = Customer();
            customer.id = NSUUID(UUIDString: result.stringForColumn("customerId"))
            customer.firstName = result.stringForColumn("firstName")
            customer.lastName = result.stringForColumn("lastName")
            customer.title = result.stringForColumn("title")
            return customer
        }
    }
    else {
        println("Error: \(db.lastErrorMessage())")
    }
    return nil
}

Solution

  • The NULL values are returned as nil:

    db.executeUpdate("create table foo (bar text)", withArgumentsInArray: nil)
    db.executeUpdate("insert into foo (bar) values (?)", withArgumentsInArray: ["baz"])
    db.executeUpdate("insert into foo (bar) values (?)", withArgumentsInArray: [NSNull()])
    
    if let rs = db.executeQuery("select * from foo", withArgumentsInArray: nil) {
        while rs.next() {
            if let string = rs.stringForColumn("bar") {
                println("bar = \(string)")
            } else {
                println("bar is null")
            }
        }
    }
    

    That outputs:

    bar = baz
    bar is null

    You might want to double check how the values were inserted. Specifically, were empty values added using NSNull? Or perhaps open the database in an external tool and verify that the columns are really NULL like you expected.