You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:29:56