选择每一行,更新它,然后移动到下一行:表中没有主键

时间:2013-11-22 00:55:47

标签: c# asp.net sql sql-server sql-server-2008-r2

我有一个情况,我受到许多限制,所以请帮助我。

我的数据库中有一个包含250万行且没有主键的表,因为我们将在下一次迭代中清理数据。

列格式为

   [District], [Town Name], [Plant Height]

[Plant Height]中的数据格式不正确,所以我想迭代所有行,选择[Plant Height]单元格值将其转换为某种格式,然后更新它。我无法使用该方法进行读取然后更新,因为更新需要where条件,并且我在此表中没有主键,而其他事情是我将不得不等待整晚来处理这250万记录,所以这不是一个选项。

所以,如果你能建议一些可靠的方法,我可以加载数据,然后逐行更新,我会非常感激

谢谢

4 个答案:

答案 0 :(得分:3)

您可以UPDATE使用CASE在一列上应用转换,而无需WHERE子句。

检查[PlantHeight]列所在的格式,然后应用所需的转换,例如:

UPDATE myTableName  
SET     [PlantHeight] =  
 CASE  
   WHEN [PlantHeight] = <condition> THEN <apply transform cm to inches>
   WHEN [PlantHeight] = <condition> THEN <apply transform m to inches>
 END 

答案 1 :(得分:1)

您可以执行以下步骤:

  1. 创建一个临时或非临时表,其结构与您的表相同,但带有主键(自动增量)。

  2. 在第1点创建的表中进行清理,使用主键移动记录。

  3. 将已清理的记录复制回原始表格。

  4. 或者,只有在可以修改原始表的情况下,才可以为清理添加主键。

答案 2 :(得分:0)

您的表中是否有任何列或一组具有可用作唯一键的值的列?如果是这样,您可以使用该列进行更新...如果没有,请告诉我们您需要对该列进行哪种处理。在其他情况下,我认为在这种情况下,带有身份主键的建议临时表是一个不错的选择。

答案 3 :(得分:0)

如果您熟悉LINQ to Entities和Entity Framework,则可以创建一个简单的控制台应用程序来完成此任务。从数据库/表创建实体数据模型。然后,您需要创建一个循环来进行转换,并在每次传递时推进变量,如下所示。 orderby是必需的,以促进Skip / Take方法,每个周期将处理分成10,000条记录:

 class Program
{
    static void Main(string[] args)
    {
        int i = 0;
        i = QueryRecords(i);
    }

    private static int QueryRecords(int i)
    {
        using (YourEntityModel db = new YourEntityModel())
        {
            var query = (from p in db.Plants
                         select p).OrderBy(x => x.TownName).Skip(i).Take(10000);

            if (query.Count() >= 1)
            {
                ProcessRecords(i, query);
            }
            else
            {
                Console.WriteLine("Reached end of records");
                Console.ReadLine();
            }
        }
        return i;
    }

    private static void ProcessRecords(int i, IQueryable<Plants> query)
    {
        foreach (Plants item in query)
        {
                //Do your transform
                //    item.PlantHeight = PlantHeight **converted to inches**
                //db.SaveChanges();
        }
        i = i + 10000;
        QueryRecords(i);
    }
}