SQLite在使用参数和事务时不插入多于一行

Posted

技术标签:

【中文标题】SQLite在使用参数和事务时不插入多于一行【英文标题】:SQLite not inserting more than one row when using parameters and transaction 【发布时间】:2021-12-11 02:49:32 【问题描述】:

我在 Windows UWP 应用程序中使用 SQlite 有一个奇怪的现象。

我正在尝试使用事务进行批量插入,但我只在数据库中插入了一行,或者出现错误消息“必须为以下参数添加值:”但错误消息中没有显示任何参数,并且我所有的参数都包含有效值。

这是代码


    string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, _dbName);

    using (SqliteConnection db = new SqliteConnection($"Filename=dbpath"))
    
        db.Open();
        using (var insertCommand = db.CreateCommand())
        
            using (var insertTransaction = db.BeginTransaction())
            
                insertCommand.Transaction = insertTransaction
                
                insertCommand.CommandText = $"INSERT INTO tableName (Id) VALUES (@Id)";

                foreach (var aktor in aktors)
                
                    
                    insertCommand.Parameters.AddWithValue("@id", aktor.Id);
                    await insertCommand.ExecuteNonQueryAsync();
                
                
                insertTransaction.Commit();
            
        
        db.Close();
    
    return true;

【问题讨论】:

【参考方案1】:

每次向现有参数添加新参数时,您的代码中都有错误。试试这个

insertCommand.Parameters.AddWithValue("@id", 0);

foreach (var aktor in aktors)


  insertCommand.Parameters[0].Value = aktor.Id;
  // or
  insertCommand.Parameters["@id"].Value = actor.Id;

  await insertCommand.ExecuteNonQueryAsync();
 

【讨论】:

【参考方案2】:

对循环中的每个项目执行一个 INSERT 命令,然后提交:


    string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, _dbName);

    using (SqliteConnection db = new SqliteConnection($"Filename=dbpath"))
    
        db.Open();
        using (var insertTransaction = db.BeginTransaction())
        
            foreach (var aktor in aktors)
            
                using (var insertCommand = db.CreateCommand())
                
                    insertCommand.Transaction = insertTransaction;
                    insertCommand.CommandText = $"INSERT INTO tableName (Id) VALUES (@Id)";
                    insertCommand.Parameters.AddWithValue("@id", aktor.Id);
                    await insertCommand.ExecuteNonQueryAsync();
                
            
            insertTransaction.Commit();
        
        db.Close();
    
    return true;

【讨论】:

使用这种方法我认为性能会受到影响,因为代码会尝试为每次迭代而不是一次优化 sql 查询。 您执行多个 INSERT 命令的方法一开始就没有性能。如果您想要性能,请执行一个查询。

以上是关于SQLite在使用参数和事务时不插入多于一行的主要内容,如果未能解决你的问题,请参考以下文章

即使有事务,SQLite 插入也会变慢

使用事务的 Android SQLite 批量插入

在sqlite3中,插入事务中的选择可以成功吗?

SQLITE3插入大量数据,效率翻百倍

sqlite性能优化

C# sqlite 事务提交多个语句,提升插入速度