我已编写附加函数,将自定义c#list中的数据插入到MSAccess中。
第一个只为每个记录集设置一个新连接:
public static void appenddatatotable(string connectionstring, string tablename, string[] values)
{
var myconn = new OleDbConnection(connectionstring);
var cmd = new OleDbCommand();
cmd.CommandText = "INSERT INTO " + tablename + " ([RunDate],[ReportingGroup], [Tariff], [Year]) VALUES(@RunDate, @ReportingGroup, @Tariff, @Year)";
cmd.Parameters.AddRange(new[] { new OleDbParameter("@RunDate", values[0]), new OleDbParameter("@ReportingGroup", values[1]), new OleDbParameter("@Tariff", values[2]), new OleDbParameter("@Year", values[3])});
cmd.Connection = myconn;
myconn.Open();
cmd.ExecuteNonQuery();
myconn.Close();
}
然后我简单地遍历我的值列表并在每次迭代时调用此函数。这很好但很慢。
在第二个函数中,我尝试在函数中包含循环并使用BeginTransction和Committransaction:
public static void appenddatatotable2(string connectionstring, string tablename, string datstr, List<PowRes> values)
{
var myconn = new OleDbConnection(connectionstring);
int icounter = 0;
var cmd = new OleDbCommand();
OleDbTransaction trans = null;
cmd.Connection = myconn;
myconn.Open();
foreach (var item in values)
{
if (icounter == 0)
{
trans = cmd.Connection.BeginTransaction();
cmd.Transaction = trans;
}
cmd.CommandText = "INSERT INTO " + tablename + " ([RunDate],[ReportingGroup], [Tariff], [Year]) VALUES(@RunDate, @ReportingGroup, @Tariff, @Year)";
if (string.IsNullOrEmpty(item.yr))
item.yr = "";
cmd.Parameters.AddRange(new[] { new OleDbParameter("@RunDate", datstr), new OleDbParameter("@ReportingGroup", item.RG), new OleDbParameter("@Tariff", item.tar), new OleDbParameter("@Year", item.yr)});
cmd.ExecuteNonQuery();
icounter++;
if (icounter >= 500)
{
trans.Commit();
icounter = 0;
}
}
if (icounter > 0)
{
trans.Commit();
}
myconn.Close();
}
这也可以正常工作但速度慢。
我的代码错了吗?我怎样才能加快多次插入?
谢谢!
答案 0 :(得分:1)
没有测试,只是我对你的第二个函数的猜测:你在循环中向同一个命令添加了太多参数 - cmd.Parameters在每次使用之前都没有被清除..
通常在一个连接中提交大量命令比在单个连接中逐个提交命令要快得多。
加速插入的另一种方法是将所有插入语句转储为长文本,用分号分隔,然后一次性触发提交(我不确定msAccess是否支持它)
编辑:
将update命令合并为一个文本:
var updates = values.Select(x => string.Format("INSERT INTO myTable ([RunDate],[ReportingGroup], [Tariff], [Year]) VALUES({0}, {1}, {2}, {3})",
datstr, x.RG, x.tar, x.yr))
.Aggregate((m, n) => m + ";" + n);
cmd.CommandText = update;
虽然这可能有SQL注入问题。
答案 1 :(得分:1)
这应该明显快于所有现有版本
public static void appenddatatotable2(string connectionstring, string tablename, string datstr, List<PowRes> values)
{
string commandText = "INSERT INTO " + tablename + " ([RunDate],[ReportingGroup], [Tariff], [Year]) VALUES(@RunDate, @ReportingGroup, @Tariff, @Year)";
using (var myconn = new OleDbConnection(connectionstring))
{
myconn.Open();
using (var cmd = new OleDbCommand())
{
foreach (var item in values)
{
cmd.CommandText = commandText;
cmd.Parameters.Clear();
cmd.Parameters.AddRange(new[] { new OleDbParameter("@RunDate", datstr), new OleDbParameter("@ReportingGroup", item.RG), new OleDbParameter("@Tariff", item.tar), new OleDbParameter("@Year", item.yr) });
cmd.Connection = myconn;
cmd.Prepare();
cmd.ExecuteNonQuery();
}
}
}
}