如何使用 C# 程序中的新值快速更新表中的所有行
Posted
技术标签:
【中文标题】如何使用 C# 程序中的新值快速更新表中的所有行【英文标题】:How To Quickly Update All The Rows In A Table With New Value From A C# Program 【发布时间】:2014-11-06 13:50:09 【问题描述】:我得到了一张包含超过 20 亿行的表格。它有一个输入时间的字段,但表的创建者将此字段设为字符串字段。它也不遵循正常的日期时间约定。
我的任务是创建一个新字段,它是一个包含相同时间但转换为正确格式的日期时间类型字段,以便可以在其上运行查询。
目前我编写了一个 C# 控制台应用程序,它选择尚未更新的前 100000 行,并逐行将字符串转换为时间。然后它更新每一行。
此过程有效,但速度很慢,而且时间至关重要。我可以运行我的程序的多个副本,并试图提出一个解决方案,以某种方式多次运行程序并确保程序的每个副本都更新不同的行。
目前的想法:
而不是选择前 100000 行,而是选择 1000000 随机行。 (可能会有一些重叠,但可以完成工作) 此表有一个 id 字段。我可以选择其中一个程序 id modulo 2 == 0,另一个程序 id % 2 != 0 (对于素数等,这可以继续) 仅在为我正在运行的每个程序副本指定的 id 范围内获取行 添加一个锁定的列来告诉我的程序一个字段当前被锁定(这表示它正在被处理)谁能提供更好的建议?改进我的一个?
谢谢。
更新:我现有时间字符串的一个示例是 12/Nov/2014:08:52:22,它需要转换为 2014-11-12 08:42:22
【问题讨论】:
为什么不使用 SQL Server 进行转换,而不是在数据库和控制台应用程序之间来回切换? 您的数据是否遵循相同的格式?您应该尝试为此使用 SQL 服务器:***.com/questions/1509977/… 我同意,只需在管理工作室中运行它并在等待时喝杯咖啡。 但是,有没有可能超时或直接在sql server中运行会减慢服务器的其他进程。 如果您必须在控制台应用程序中执行此操作,请查看 LINQ to SQL 以及可用的 Skip() 和 Take() 扩展方法。 【参考方案1】:使用 LINQ to SQL,一次只提取一定数量的记录。
您的代码看起来应该是这样的:
using (var db = new MyDbContext())
var results = db.GetResultsFromDatabase();
int take = 100;
int processed = 0;
while(processed < results.Count())
var set = results.Skip(processed).Take(take);
set.ForEach(s =>
// update the date
processed += take;
db.SubmitChanges();
【讨论】:
这基本上是我已经在做的事情。我需要一些东西能够同时运行相同的东西,但处理不同的记录。【参考方案2】:所以这是我的解决方案,我不知道 200 万行的效果如何,以防你想在 SQL 中执行。
Declare @string varchar(50) = '12/Nov/2014:08:52:22'
SELECT CONVERT(datetime,REPLACE(SUBSTRING(@string,0,CHARINDEX ( ':' ,@string , 0)),'/',' ')
+' '+
SUBSTRING(@string,CHARINDEX ( ':' ,@string , 0)+1,LEN(@string)),120)
让我解释一下代码
REPLACE(SUBSTRING(@string,0,CHARINDEX ( ':' ,@string , 0)),'/',' ')
替换日期中的“/”字符并返回 2014 年 11 月 12 日
SUBSTRING(@string,CHARINDEX ( ':' ,@string , 0)+1,LEN(@string)),120)
从您的初始字符串中获取日期和时间之间没有“:”的时间。
最后在这两个字符串操作之间加了一个空格,并将其转换为日期时间。
上述查询的输出:'2014-11-12 08:52:22.000'
【讨论】:
【参考方案3】:只需在 SQL 中执行,而不是读取整个数据库并运行它。
使用以下内容:
UPDATE <TableName>
SET <dateTime-Date> = CONVERT(datetime, <string-Date>)
查看此站点以获取您想要的任何格式规范: SQL Datetime Conversion
【讨论】:
基于我当前的日期字符串,我不相信我可以简单地转换它。 你能举一个日期字符串的例子吗?我们也许可以帮助或至少告诉您它是否可转换。 更新了第一篇文章。当前字符串是 12/Nov/2014:08:52:22 我希望它是 2014-11-12 08:42:22 这是一种非常不常见的保存日期的方法。无论如何,我建议首先将所有 NOV、DEC、JAN 月份名称更改为数值,然后激活 CONVERT 功能。您可以使用 Switch case 来确定哪个 no 与哪个月份相关。完成后,您的日期将采用有效格式。 12/11/2014 08:52:22,然后就可以使用convert方法了。以上是关于如何使用 C# 程序中的新值快速更新表中的所有行的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Java Spring Boot 在不插入新值的情况下更新表中的现有值
MySQL ------ 更新数据(UPDATE)(二十一)