【问题标题】:C# update database table using SQL using values from a DataTable that is not in SQL ServerC# 使用 SQL 使用不在 SQL Server 中的 DataTable 中的值更新数据库表
【发布时间】:2017-01-10 18:24:54
【问题描述】:

我有一个 SQL Server 数据库表,我需要使用从外部源检索到的 C# 应用程序 DataTable 中的值来更新它(它可能来自文件、外部 API 调用等,我猜这无关紧要) .

有没有办法使用类似于以下的 SQL 进行“大规模”更新:

UPDATE myTable1 t1
SET    custAddress = t2.address
FROM   myTable2 t2
WHERE  t1.id = t2.id

我想我可以使用上面的示例,只要两个表都在同一个 SQL Server 数据库中;但在本例中,myTable2 是应用程序 (C#) DataTable 而不是 SQL Server 表。

有没有办法完成类似于上面的更新?

我知道我可以“循环”遍历每个应用程序表行并为每一行触发 SQL 更新,但如果我的数据表有数千行,我不希望(只要可能)必须执行一个 SQL更新我需要更新的每一行。

任何帮助将不胜感激。我愿意接受涉及 LINQ 或任何其他 C# 或 SQL 逻辑的解决方案或建议。

【问题讨论】:

  • 您必须为此编写代码。没有内置函数可以大规模执行。
  • 批量加载到 SQL 中的临时表,然后更新所有行

标签: c# sql sql-server linq


【解决方案1】:
  1. 获取数据表 (C#) 并将其转换为 xml。提示,如果您将数据表添加到数据集,您可以调用 ds.GetXml()。 (见here

  2. 将 xml 推送到 sql-server。

  3. 使用 sql-server-xml 功能将 xml 分解为 #temp 或 @variable 表。

  4. 使用 #temp 或 @variable 表中的数据执行 CUD(创建/更新/删除)操作。

基本思路在这里:

HOW TO: Perform Bulk Updates and Inserts Using OpenXML with .NET Providers in Visual C# .NET

但您不想使用 OPENXML(Sql Server 2000 语法),而是使用“此处找到的粉碎”示例:

http://pratchev.blogspot.com/2007/06/shredding-xml-in-sql-server-2005.html

恕我直言:这是为 CUD(创建/更新/删除)执行“基于集合”操作的好方法。这样做的最大好处之一是所有索引更新都发生在基于集合的操作之后,如果你这样做 RBAR(逐行),索引必须在每次操作后重建。 :(

注意,#3 (b) 是可选的。你必须切碎。但是,您可以直接从 xml-shredding 转到“真实”表(并跳过 #temp 或 @variable 表)。我通常测试真实世界的“负载”(xml 数据量),如果没有太大区别,我坚持使用#temp 或@variable 表。以后更容易调试,因为您可以输入一个临时“select * from #myTempTable”并查看数据是否正确粉碎。您还应该测试 #temp 与 @variable 表。有时它会有所作为。

请注意,基于元素的 xml 存在一个古老的“性能”错误。

https://connect.microsoft.com/SQLServer/feedback/details/250407/insert-from-nodes-with-element-based-xml-has-poor-performance-on-sp2-with-x64

它可能不再适用。但这是需要注意的。 “回到过去”(由于注入的错误)​​我和我的团队必须将基于元素的 xml 更改为基于属性的 xml(在 C# 中),然后再将其发送到 sql-server。

【讨论】:

    【解决方案2】:

    我认为最直接的方法是使用SqlBulkCopy 将您的应用程序数据批量插入到临时表中。如果您想批量执行此操作,还可以选择设置batch size

    在批量插入之后,运行一个存储过程来进行更新。另一种选择是使用插入后触发器,但这似乎只有在批量插入时才有意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      • 2011-12-31
      • 2011-12-31
      相关资源
      最近更新 更多