我有一个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逻辑的解决方案或建议。
答案 0 :(得分:2)
获取数据表(C#)并将其转换为xml。提示,如果将数据表添加到数据集,则可以调用ds.GetXml()。 (见here)
将xml推送到sql-server。
使用sql-server-xml功能将xml“分解”为#temp或@variable表。
使用#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 vs @variable表。有时它会产生影响。
请注意,基于元素的xml存在旧的“性能”错误。
它可能不再适用。但需要注意的是。 “回到当天”(因为注入了错误)我的团队和我必须将基于元素的xml更改为基于属性的xml(在C#中),然后再将其发送到sql-server。
答案 1 :(得分:1)
我认为最直接的方法是使用SqlBulkCopy将应用程序数据批量插入到临时表中。如果您想批量执行此操作,还可以选择设置batch size。
批量插入后,运行存储过程以执行更新。另一种选择是使用后插入触发器,但这似乎只有在批量插入批量时才有意义。