从 Objective-C 版本桥接的 FMDB API 似乎没有直接的方法来检查 NULL 值(请纠正我,如果我错了,请)。因此,对于定义为的数据库列,例如,
myColumn BigInt NULL
NULL 值将在涉及该列的任何 FMResultSet 中显示为值 0,使用 Swift 代码,如问题所示。
(当碰巧在顶部有一个 UNIQUE 约束时,这将产生特别令人惊讶的结果。NULL 值将从数据库中检索为 0,以便在下一次保存操作时可能会更新,这违反了唯一性涉及多个实体时的约束,如我的情况。但是,基础问题与约束无关。因此,我将重点关注一般的 NULL 值问题。)
为了避免这个问题,我们必须首先从相应的 FMResultSet 中检索列的值作为对象,如下所示:
let objectValue = resultSet.objectForColumn("myColumn")
如果objectValue 恰好是 NSNull() 类型/值,那么我们有一个 NULL 值并且可以相应地处理它。否则,我们可以使用普通的longForColumnName 方法。 (然而,对于字符串等对象类型,FMDB 实现自然会返回一个可选项,对于 NULL 的数据库值,该选项将为 nil!)
为了使这更容易,我使用了 FMResultSet 类的扩展(用于按索引检索,我更喜欢),如下所示:
extension FMResultSet {
func isNullForColumnIndex(columnIdx: Int32) -> Bool {
let value = self.objectForColumnIndex(columnIdx)
if let nullValue = value as? NSNull {
return true
} else {
return (value == nil)
}
}
}
假设“myColumn”将出现在结果集中的索引 0 处,这会将上面示例中的数字类型的值提取减少为这样的一行:
let num: Int64? = (result.isNullForColumnIndex(0) ? nil : Int64(result.longForColumnIndex(0)))
当然,我也可以添加一个方法,例如,optionalLongForColumnIndex(columnIndex: Int32) -> Int64?,它将包括 NULL 检查和值检索。这只需要对每种值类型都使用一种这样的方法,到目前为止我一直避免使用这种方法。