【问题标题】:Populate new field in SQLite database using existing field value and a C# function使用现有字段值和 C# 函数填充 SQLite 数据库中的新字段
【发布时间】:2019-07-24 23:41:03
【问题描述】:

我有一个 SQLite 数据库,我想根据现有数据库为其填充一个新字段。我想使用 C# 函数导出新的字段值。

在伪代码中,它会是这样的:

foreach ( record in the SQLite database)
{
my_new_field[record_num] = my_C#_function(existing_field_value[record_num]);
}

查看 StackOverflow 上的其他建议后,我使用 SqliteDataReader 读取每条记录,然后根据特定 RowId 运行 SQlite“更新”命令来更新同一记录的新字段值。

它可以工作....但它真的很慢,并且像疯了一样敲打硬盘。真的没有更好的方法吗?

我需要更新的一些数据库可能有数百万条记录。

提前感谢您的帮助。

编辑:

作为对评论的回应,这里有一些真实的代码,使用一种称为 Concordance CPL 的遗留语言。需要注意的重要一点是,您可以一次读取和写入对当前记录的更改:

int db;

cycle(db)
{
db->FIRSTFIELD = myfunction(db->SECONDFIELD);
}

myfunction(text input)
{
text output;

/// code in here to derive output from input

return output;
}

我觉得在 SQLite 中没有等效的方法可以做到这一点,因为 SQL 本质上是事务性的,而 Concordance 允许您按顺序遍历和更新数据库。

【问题讨论】:

  • ...看起来我应该能够通过将所有更新包装在单个事务中来提高性能。但是,我认为我的问题仍然是多个更新查询是否是正确的架构。谢谢。
  • 可能还有很多其他的方式,从假的伪代码中很难分辨。
  • 很难解释为什么你以前的代码这么慢,因为你的伪伪代码没有用(尽管添加了更多抽象的 CPL)。它没有透露任何实际的 C# 对象或 SQL 语句...对于寻求性能等方面的帮助而言关键的细节。因为 sqlite 是一个进程内嵌入式 DBMS,它允许custom functions进行定义,以便您可以执行 UPDATE mytable SET FIRSTFIELD = myfunction(SECONDFIELD)... 之类的操作,与 CPL sn-p 非常相似。
  • 谢谢。好的。我可能应该更具体地回答我的问题。我对编码没有任何困难。我的查询对原理进行了更有意义的检查:即更新 SQLite 数据库中所有行的 only 方法是否是通过引用不同 RowID 的多个 UPDATE 命令。答案似乎是“是”,因为即使您使用 SQLDataAdapter 仍然只是在幕后创建 UPDATE 命令。
  • stackoverflow.com/questions/172735/… 抱歉,我现在无法通过更完整的代码示例来挖掘我对它们的使用,但这是使用 system.data.sqlite 的 C# 的开始(可以轻松使用 nuget 添加到 Visual Studio 项目中)。

标签: c# system.data.sqlite


【解决方案1】:

解决方案是将所有更新包装到一个事务中。

这里有一个用于批量插入的示例: https://www.jokecamp.com/blog/make-your-sqlite-bulk-inserts-very-fast-in-c/

在我的例子中,这将是基于 RowID 的批量更新,打包到单个事务中。

它现在可以工作了,而且性能要好很多个数量级。

编辑:根据上面有用的评论,定义一个自定义 C# 函数,然后在单个 UPDATE 命令中引用它也很有效,并且在某些方面比上面的更好,因为您不必在 C# 本身内循环.参见例如Create/Use User-defined functions in System.Data.SQLite?

【讨论】:

  • 这有助于改进您的代码,非常棒。但即使链接页面中的代码仍然不完整,也没有使用最佳实践。您可能会加快速度。定义 SQLiteCommand 对象的目的是创建一个参数化的 prepared(即类似于预编译语句)语句,然后您只需传入数据并重新执行该语句。链接代码重复重新定义cmd.CommandText...效率不高。查看 SQLiteCommand 参数。简单地包装事务可能不会在性能上获得数量级。
  • 谢谢。是的,我在我的代码中使用了参数。该命令在“using”语句中定义,只有参数在循环每条记录时更新。
猜你喜欢
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多