簡體   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