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

SQLite多表存储异常:批量保存通话记录仅最后一条生效

问题排查与解决方案

1. 检查SqlHelper中SQLiteConnection的复用逻辑

如果你的SqlHelper复用同一个SQLiteConnection实例,且插入操作时未正确重置参数,会导致参数被覆盖,最终只有最后一条数据插入成功。

  • 修正方案:确保每次插入操作使用独立的SQLiteCommand实例,或在循环前清空参数集合
    // 错误示例:复用command未重置参数
    var command = connection.CreateCommand();
    command.CommandText = "INSERT INTO CallHistory (Id, Number, Duration) VALUES (@Id, @Number, @Duration)";
    foreach(var record in records)
    {
        command.Parameters.AddWithValue("@Id", record.Id);
        // 未移除旧参数,多次循环后参数累积覆盖,仅最后一次生效
        command.ExecuteNonQuery();
    }
    
    // 正确示例:每次循环创建新command
    foreach(var record in records)
    {
        using(var command = connection.CreateCommand())
        {
            command.CommandText = "INSERT INTO CallHistory (Id, Number, Duration) VALUES (@Id, @Number, @Duration)";
            command.Parameters.AddWithValue("@Id", record.Id);
            command.Parameters.AddWithValue("@Number", record.Number);
            command.Parameters.AddWithValue("@Duration", record.Duration);
            command.ExecuteNonQuery();
        }
    }
    

2. 启用事务处理优化批量插入

批量插入未使用事务不仅效率低下,还可能因隐式的连接状态问题导致数据丢失。同时事务能保证操作的原子性:

using(var connection = new SQLiteConnection("Data Source=your_local.db"))
{
    connection.Open();
    using(var transaction = connection.BeginTransaction())
    {
        try
        {
            foreach(var record in records)
            {
                using(var command = connection.CreateCommand())
                {
                    command.Transaction = transaction;
                    command.CommandText = "INSERT INTO CallHistory (Id, Number, Duration) VALUES (@Id, @Number, @Duration)";
                    command.Parameters.AddWithValue("@Id", record.Id);
                    command.Parameters.AddWithValue("@Number", record.Number);
                    command.Parameters.AddWithValue("@Duration", record.Duration);
                    command.ExecuteNonQuery();
                }
            }
            transaction.Commit();
        }
        catch(Exception ex)
        {
            transaction.Rollback();
            throw;
        }
    }
}

3. 验证实体类与表结构的映射

如果使用ORM框架(如SQLite-net),检查通话记录实体的主键设置:

  • 若所有记录使用相同的主键值,插入时会覆盖之前的数据
  • 修正方案:将主键设为自增类型,或确保每条记录的主键唯一
    public class CallHistory
    {
        [PrimaryKey, AutoIncrement] // 开启自增避免主键冲突
        public int Id { get; set; }
        public string PhoneNumber { get; set; }
        public int CallDuration { get; set; }
        public DateTime CallTime { get; set; }
    }
    

4. 开启SQLite日志排查执行语句

通过日志查看实际执行的SQL语句,确认每次插入的参数是否正确:

SQLiteConnection.SetConfiguration(new SQLiteConfig { Log = (message) => Console.WriteLine(message) });

日志会输出每条INSERT语句的参数值,可直接定位是否存在参数覆盖或重复的问题。


内容的提问来源于stack exchange,提问作者Matthew Pans

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 18:52:17