繁体   English   中英

C#使用不在SQL Server中的数据表中的值使用SQL更新数据库表

[英]C# update database table using SQL using values from a DataTable that is not in SQL Server

我有一个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逻辑的解决方案或建议。

  1. 取得数据表(C#)并将其转换为xml。 提示,如果将数据表添加到数据集,则可以调用ds.GetXml()。 (请参阅此处

  2. 将xml推送到sql-server。

  3. 使用sql-server-xml功能将xml“切碎”到#temp或@variable表中。

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

基本思想在这里:

HOW TO:在Visual C#.NET中使用OpenXML和.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 from #myTempTable”,然后查看数据是否被正确粉碎。 您还应该测试#temp与@variable表。 有时会有所作为。

请注意,element-based-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。

我认为最简单的方法是使用SqlBulkCopy将应用程序数据批量插入到临时表中。 如果要分批设置,还有一个选项可以设置批量大小

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM