如何使用ADO.NET更新大表

时间:2009-05-26 04:06:00

标签: c# ado.net

好的,所以这是我必须解决的问题。我需要在C#中编写一个方法来修改SQL Server 2008中的表。该表可能包含数百万条记录。修改包括通过添加新列来更改表,然后为表中的每一行计算和设置新字段的值。

添加列不是问题。它正在有效地设置值,这是问题所在。我不想将整个表读入DataTable,然后出于显而易见的原因进行更新和提交。我想我想使用游标迭代表中的行并逐个更新它们。我没有做过很多ADO.NET开发,但我的理解是只支持只读服务器端(firehose)游标。

那么做这样的事情的正确方法是什么(最好用C#中的一些示例代码)?不允许对数据库进行存储过程或其他此类修改。

3 个答案:

答案 0 :(得分:2)

jpgoody,

这是一个使用NerdDinner数据库和一些SQLConnection,SQLCommand和SQLDataReader对象进行咀嚼的示例。它会在晚餐表格中为每个活动日期添加一天。

using System;
using System.Data.SqlClient;

namespace NerdDinner
{
    public class Class1
    {
        public void Execute()
        {
            SqlConnection readerConnection = new SqlConnection(Properties.Settings.Default.ConnectionString);
            readerConnection.Open();

            SqlCommand cmd = new SqlCommand("SELECT DinnerID, EventDate FROM Dinners", readerConnection);
            SqlDataReader reader = cmd.ExecuteReader();

            SqlConnection writerConnection = new SqlConnection(Properties.Settings.Default.ConnectionString);
            writerConnection.Open();

            SqlCommand writerCommand = new SqlCommand("", writerConnection);

            while (reader.Read())
            {
                int DinnerID = reader.GetInt32(0);
                DateTime EventDate = reader.GetDateTime(1);

                writerCommand.CommandText = "UPDATE Dinners SET EventDate = '" + EventDate.AddDays(1).ToString() + "' WHERE DinnerID = " + DinnerID.ToString();
                writerCommand.ExecuteNonQuery();
            }
        }
    }
}

答案 1 :(得分:1)

您的问题看起来像是应该使用T-SQL而不是C#解决的问题,除非您有一些业务规则要动态获取并计算列值T-SQL应该是要走的路。只需编写存储过程或只需打开Management studio并编写代码即可进行更改。
如果这没有用,那么请详细说明你想对表做什么完全,然后我们可以帮助你弄清楚是否可以通过T-SQL完成。

[编辑]你可以做这样的事情

    string sql = " USE "  + paramDbName;
    sql+= " ALTER TABLE XYZ ADD COLUMN " + param1 + " datatype etc, then put semicolon to separate the commands as well"
    sql+= " UPDATE  XYZ SET Columnx = " + some logic here
    cmd.CommandText = sql;
    cmd.ExecuteNonQuery();

在所需的Sql Server 2008实例上执行此操作 如果你有太多的文本行,那么使用StringBuilder。

答案 2 :(得分:0)

这是一个建议: 您可以使用DataReader读取数据,为当前行创建更新命令并将其添加到命令列表中。然后在事务中运行update命令。 像这样的东西:

var commands=new List<SqlCommand>();
while(dr.Read())
{
var cmd=new SqlCommand();

cmd.CommandText="Add your command text here";
commands.Add(cmd);
}


using(var cnn=new SqlConnection("Connection String"))
{
IDbTransaction transaction;
try
{
cnn.Open();
transaction=cnn.BeginTransaction();
foreach(var cmd in commands)
{
cmd.Transaction=transaction;
cmd.ExecuteNonQuery();
cmd.Dispose(); 
}
transaction.Commit();
}
catch(SqlException)
{
if(transaction!=null)
transaction.Rollback();
throw;
}
}