好的,所以这是我必须解决的问题。我需要在C#中编写一个方法来修改SQL Server 2008中的表。该表可能包含数百万条记录。修改包括通过添加新列来更改表,然后为表中的每一行计算和设置新字段的值。
添加列不是问题。它正在有效地设置值,这是问题所在。我不想将整个表读入DataTable,然后出于显而易见的原因进行更新和提交。我想我想使用游标迭代表中的行并逐个更新它们。我没有做过很多ADO.NET开发,但我的理解是只支持只读服务器端(firehose)游标。
那么做这样的事情的正确方法是什么(最好用C#中的一些示例代码)?不允许对数据库进行存储过程或其他此类修改。
答案 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;
}
}