繁体   English   中英

如何使用ADO.NET更新大表

[英]How to update a large table using ADO.NET

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

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

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

jpgoody,

下面是一个使用NerdDinner数据库和一些SQLConnection,SQLCommand和SQLDataReader对象进行咀嚼的示例。 它为Dinners表中的每个事件日期添加了一天。

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();
            }
        }
    }
}

您的问题看起来像是应该使用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。

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

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;
}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM