如何使用FMDB删除数据库文件中所有表的全部数据行
问题描述
想要创建一个通用方法,用于删除项目中指定数据库文件里所有表的全部数据行。不想存储或传递所有表名,方法仅需接收数据库文件路径即可运行。目前已经写出获取所有表名的代码,但不清楚执行fmdb.executeQuery之后该如何操作,也不知道在哪里调用DELETE FROM \(tableName)语句。
代码片段:
guard let path = getDBPath(for: .contacts), let dbQueue = FMDatabaseQueue(path: path) else { return } dbQueue.inDatabase { fmdb in do { let resultSet = try fmdb.executeQuery( "SELECT name FROM sqlite_master WHERE type='table'", values: nil ) // what is next? } catch { // log error } }
解决方案
你可以通过遍历查询结果集获取所有表名,然后逐个执行DELETE语句。另外建议用事务包裹批量操作,提升效率同时保证原子性。
完整代码示例:
func clearAllDataInDatabase(atPath path: String) { guard let dbQueue = FMDatabaseQueue(path: path) else { // 处理数据库队列初始化失败的情况 return } dbQueue.inTransaction { fmdb, rollback in do { // 查询所有用户自定义表(排除SQLite系统表) let resultSet = try fmdb.executeQuery( "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'", values: nil ) // 遍历结果集获取表名 while resultSet.next() { guard let tableName = resultSet.string(forColumn: "name") else { continue } // 执行DELETE语句清空表数据 try fmdb.executeUpdate("DELETE FROM \(tableName)", values: nil) } // 如果所有操作成功,不需要回滚 rollback.pointee = false } catch { // 捕获错误,标记回滚 rollback.pointee = true // 这里可以添加错误日志逻辑 print("清空数据库失败:\(error.localizedDescription)") } } } // 调用示例 if let path = getDBPath(for: .contacts) { clearAllDataInDatabase(atPath: path) }
关键说明:
- 排除系统表:SQLite自带一些以
sqlite_开头的系统表(比如sqlite_sequence),这些表不应该被清空,所以查询时加AND name NOT LIKE 'sqlite_%'过滤。 - 事务处理:用
inTransaction替代inDatabase,批量操作时事务能大幅提升性能,而且一旦某一步出错可以整体回滚,避免数据不一致。 - 遍历结果集:通过
resultSet.next()循环移动游标,直到结果集遍历完毕,每次循环用resultSet.string(forColumn: "name")获取当前表名。
内容的提问来源于stack exchange,提问作者Oranutachi
相关产品推荐
相关产品推荐

