我的功能:删除给定表格
的特定行中的单位private static void removeUnits(String connectionString, String tableName, String columnID, String columnToFix)
{
List<String> rowsToEdit = new List<String>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT " + columnID + "," + columnToFix + " FROM " + tableName;
connection.Open();
using (var reader = command.ExecuteReader())
{
var indexOfR_MEASUREDVALUEID = reader.GetOrdinal(columnID);
var indexOfT_VALUE = reader.GetOrdinal(columnToFix);
while (reader.Read())
{
var t_value = reader.GetValue(indexOfT_VALUE);
var t_id = reader.GetValue(indexOfR_MEASUREDVALUEID);
String newValue = getWithoutUnit(t_value.ToString());
if (newValue != null)
{
String sql = "UPDATE " + tableName + " SET " + columnToFix + "='" +
newValue + "' WHERE " + columnID + "='" + t_id + "';";
rowsToEdit.Add(sql);
}
}
connection.Close();
}
}
Console.WriteLine("start writing " + rowsToEdit.Count + " entries?");
Console.ReadLine();
SqlCommand sqlCmd;
sqlCmd = new SqlCommand("", connection);
sqlCmd.Connection.Open();
foreach (String command in rowsToEdit)
{
sqlCmd.CommandText = command;
sqlCmd.ExecuteNonQuery();
}
}
Console.WriteLine(rowsToEdit.Count + " commands executed");
}
我在Visual Studio 2010和SQL-Server 2012中使用C#。 它工作正常,但执行200000行需要很长时间。 是否可以更快地完成这项工作?
答案 0 :(得分:1)
我的建议涉及调查并行性:
注意:代码未经过测试,只需在Notepad ++中输入
即可private static void removeUnits(String connectionString, String tableName, String columnID, String columnToFix)
{
List<new Tuple<object, object>> rowsToEdit = new List<new Tuple<object, object>>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT " + columnID + "," + columnToFix + " FROM " + tableName;
connection.Open();
using (var reader = command.ExecuteReader())
{
var indexOfR_MEASUREDVALUEID = reader.GetOrdinal(columnID);
var indexOfT_VALUE = reader.GetOrdinal(columnToFix);
while (reader.Read())
{
rowsToEdit.Add(new Tuple<object, object>(reader.GetValue(indexOfT_VALUE),reader.GetValue(indexOfR_MEASUREDVALUEID)));
}
connection.Close();
}
}
}
// Use parallelism here
Parallel.Foreach(rowsToEdit, currentRow =>
{
String newValue = getWithoutUnit(currentRow.Value1.ToString());
if (newValue != null)
{
// reopen connection
// use parameters here, and call SP
}
}
Console.WriteLine("start writing " + rowsToEdit.Count + " entries?");
Console.ReadLine();
}
存储过程:
Create StoredProcedure MySP
(
@tablename varchar(50),
@columnToFix varchar(50),
@newValue varchar(50),
@columnID varchar(50),
@tID varhcar(varchar(50)
)
As
Begin
Declare @MySQL varchar(500)
Set @MySQL = 'Update ' + @tableName + ' Set ' + @columnToFix + ' = '' + @newValue + ''' + ' Where ' + @columnID + ' = '' + @tID + '''
sp_executesql @MySQL
End
重要的是要注意动态sql通常不受欢迎。这是一个讨论动态sql(优点/缺点)的链接:http://www.sommarskog.se/dynamic_sql.html
此外,您可能会遇到一些锁定/争用问题,因为您正在点击一个表(基于该功能的输入参数)。
答案 1 :(得分:0)
首先尝试使用评论中已提到的参数。其次,使用SqlCommand.Prepare()语句。实际速度还取决于您的机器容量(HD写入速度/ RAM)。以下是示例(您可能需要根据Colum类型编辑SqlDbTypes)
private static void RemoveUnits(string connectionString, string tableName, string columnID, string columnToFix)
{
Dictionary<int, string> rowsToEdit = new Dictionary<int, string>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT " + columnID + "," + columnToFix + " FROM " + tableName;
using (var reader = command.ExecuteReader())
{
var indexOfR_MEASUREDVALUEID = reader.GetOrdinal(columnID);
var indexOfT_VALUE = reader.GetOrdinal(columnToFix);
while (reader.Read())
{
string t_value = reader.GetString(indexOfT_VALUE);
int t_id = reader.GetInt32(indexOfR_MEASUREDVALUEID);
string newValue = getWithoutUnit(t_value);
if (newValue != null)
{
// save values in dictionary
rowsToEdit[t_id] = newValue;
}
}
}
}
Console.WriteLine("start writing " + rowsToEdit.Count + " entries?");
Console.ReadLine();
string updateCmd = "UPDATE " + tableName + " SET " + columnToFix + "= @Value WHERE " + columnID + "= @Key;";
using (SqlTransaction transaction = connection.BeginTransaction())
{
SqlCommand sqlCmd = connection.CreateCommand();
sqlCmd.CommandText = updateCmd;
sqlCmd.Parameters.Add("@Value", System.Data.SqlDbType.NVarChar, -1);
sqlCmd.Parameters.Add("@Key", System.Data.SqlDbType.Int);
// important for performance
sqlCmd.Prepare();
foreach (var update in rowsToEdit)
{
// change values of parameters
sqlCmd.Parameters["@Key"].Value = update.Key;
sqlCmd.Parameters["@Value"].Value = update.Value;
// and execute it
sqlCmd.ExecuteNonQuery();
}
transaction.Commit();
}
}
Console.WriteLine(rowsToEdit.Count + " commands executed");
}
编辑:如果getWithoutUnit(string)执行的操作不是很复杂,那么您可以使用TSQL执行单个语句操作,TSQL具有各种字符串操作功能。与UPDATE TableName SET StringColumn = <string manipulation TSQL here>
一样,请参阅http://msdn.microsoft.com/en-us/library/ms181984.aspx
Edit2:从评论提示中添加了事务(确实应该更快),强类型列