使用sqlite.swift读取SQLite的Blob字段崩溃:提示列值为空但实际有值
问题:SQLite.swift读取FMDB创建的Blob字段时崩溃
我用FMDB创建了SQLite数据库并插入数据,现在改用SQLite.swift替代FMDB。读取一个实际包含值的Blob类型字段时程序崩溃,报错如下:
SQLite/Query.swift:1235: Fatal error: 'try!' expression unexpectedly raised an error: Unexpected null value for column
相关代码
查询函数
func fetchAllNotes() -> [Note] { guard let db = db else { print("Database connection is not available.") return [] } var notesArray = [Note]() do { for note in try db.prepare(notes) { let note = Note( id: note[id], title: note[title], content: note[content], isdraft: note[isdraft], fontsize: note[fontsize] ) notesArray.append(note) } } catch { print("Failed to fetch notes: \(error)") } return notesArray }
Note结构体
struct Note: Identifiable { let id: Int64 let title: String let content: Blob let isdraft: Int let fontsize: Int init(id: Int64 = 0, title: String, content: Blob, isdraft: Int = 1, fontsize: Int = 16) { self.id = id self.title = title self.content = content self.isdraft = isdraft self.fontsize = fontsize } }
崩溃栈信息
_swift_runtime_on_report
libswiftCore.dylib`: -> 0x7ff8156f7320 <+0>: pushq %rbp //Crashed in this line 0x7ff8156f7321 <+1>: movq %rsp, %rbp 0x7ff8156f7324 <+4>: popq %rbp 0x7ff8156f7325 <+5>: retq 0x7ff8156f7326 <+6>: nopw %cs:(%rax,%rax)
swift_unexpectedError
0x7ff81546c3fa <+826>: pushq $0x0 0x7ff81546c3fc <+828>: pushq -0x68(%rbp) 0x7ff81546c3ff <+831>: pushq %rax 0x7ff81546c400 <+832>: pushq -0x70(%rbp) 0x7ff81546c403 <+835>: callq 0x7ff815414870 ; Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never -> 0x7ff81546c408 <+840>: nopl (%rax,%rax)
解决方案
问题核心是FMDB与SQLite.swift对Blob字段的空值处理逻辑不一致——即使你认为字段有值,可能存在部分数据中该字段实际为NULL,或者FMDB插入时允许空值但SQLite.swift读取时强制非空导致崩溃。
方法1:将Blob字段改为可选类型
修改Note结构体的content属性为可选类型,并调整初始化逻辑:
struct Note: Identifiable { let id: Int64 let title: String let content: Blob? let isdraft: Int let fontsize: Int init(id: Int64 = 0, title: String, content: Blob?, isdraft: Int = 1, fontsize: Int = 16) { self.id = id self.title = title self.content = content self.isdraft = isdraft self.fontsize = fontsize } }
查询时直接读取即可,SQLite.swift会自动处理NULL值:
let note = Note( id: note[id], title: note[title], content: note[content], isdraft: note[isdraft], fontsize: note[fontsize] )
方法2:检查并修复数据库中的NULL记录
执行SQL查询确认是否存在content字段为NULL的记录:
SELECT * FROM notes WHERE content IS NULL;
如果存在这类记录,要么更新记录填充有效Blob数据,要么在后续插入时确保该字段不为空。
方法3:SQLite.swift字段定义匹配数据库规则
确保你的notes表字段定义中,content字段允许空值。对应SQLite.swift的表达式定义也要设为可选:
let content = Expression<Blob?>("content")
内容的提问来源于stack exchange,提问作者iDevBeginner
相关产品推荐
相关产品推荐

