批量更新SQL Server C#

3
我有一个拥有主键为mid和列名为value的27万行数据库,同时我有一个文本文件,里面包含有mid和对应的values。现在我想更新这个表,使每个value都分配给正确的mid。
我的目前做法是从C#读取文本文件,并为每个读取到的行更新表中的一行。我感觉肯定有更快的方法来完成这件事..有什么想法吗?
编辑:表中还有其他列,所以我确实需要一种根据mid进行更新的方法。

你可以使用SqlBulkCopy将数据插入到临时表中,或者尝试使用带有TVP的UPDATE语句。 - ta.speot.is
2个回答

8
您可以使用 SQL Server 导入和导出向导:

http://msdn.microsoft.com/en-us/library/ms141209.aspx

或者您可以使用 BULK TSQL 语句:

BULK
INSERT YourTable
FROM 'c:\YourTextFile.txt'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)
GO


SELECT * FROM YourTable
GO

假设您正在使用逗号作为分隔符。如果您使用的是其他字符,例如空格,请将FIELDTERMINATOR更改为相应的字符。
编辑(为了实现我评论中的更新):
UPDATE RealTable
SET value = tt.value
FROM
  RealTable r
INNER JOIN temp_table tt ON r.mid = tt.mid

@Freek8 - 哦,我明白了。是的,这将从文本文件中插入。您可以使用提供的BULK查询将这些结果存储在临时表中,然后根据临时表使用UPDATE语句。 - Darren
@Freek8 - 你确定主键的索引碎片很低吗? - jahu
1
@Freek8 - 这取决于索引是聚集的还是非聚集的。在这种情况下,您将使用非聚集索引。这完全取决于SQL Server如何解释查询并编写执行计划。您可以应用它并包括实际执行计划,然后通过此来决定它是否加速/减慢了查询速度。 - Darren
@Freek8 - 应用索引,包括执行计划并运行查询。SQL Server会处理其余部分。 - Darren
@DarrenDavies 包括执行计划吗? - Freek8
显示剩余7条评论

1
你是否重复使用 SqlCommand
    struct Item
    {
        public int mid;
        public int value;
    }

    public int Update(string connectionstring)
    {
        int res = 0;
        using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand())
        using (cmd.Connection = new System.Data.SqlClient.SqlConnection(connectionstring))
        {
            cmd.CommandText = @"UPDATE [table] SET [value] = @value WHERE [mid] = @mid;";
            cmd.CommandType = CommandType.Text;
            System.Data.SqlClient.SqlParameter mid = cmd.Parameters.Add("@mid", SqlDbType.VarChar);
            System.Data.SqlClient.SqlParameter value = cmd.Parameters.Add("@value", SqlDbType.VarChar);
            try
            {
                cmd.Connection.Open();
                foreach (Item item in GetItems("pathttothefile"))
                {
                    mid.Value = item.mid;
                    value.Value = item.value;
                    res += cmd.ExecuteNonQuery();
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                cmd.Connection.Close();
            }
        }
        return res;
    }

    IEnumerable<Item> GetItems(string path)
    {
        string[] line;
        foreach (var item in System.IO.File.ReadLines(path))
        {
            line = item.Split(',');
            yield return new Item() { mid = int.Parse(line[0]), value = int.Parse(line[1]) };
        }
    }

是的,我正在重复使用 sqlcommand,但它仍然需要很长时间。 - Freek8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接