如何使用 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)(二十一)

MySQL ------ 更新数据(UPDATE)(二十一)

如何覆盖父对象的静态属性并让父对象访问 PHP 中的新值?

使用唯一随机值更新sql表中的所有行,而不使用c#中的主键或唯一键