如果要大量导入数据到数据库,如果每条数据都要和数据库建立-断开连接,那么将会非常费时。
个性化的方法:就是使用表参数和存储过程,特点是非常自由灵活,可以在存储过程中实现所需要的SQL操作。
下面这个方法生产一个Datatable
public void InsertUserAndMacByDt(string[] alarmDataArry, int ME60ID)
{
try
{
int Count = alarmDataArry.Length;
string sqlCmd = string.Empty;
string PPOE_USERNAME = string.Empty;
string USERMAC = string.Empty;
DbMan mydb = new DbMan(sqlConstr);
if (Count >= 0)
{
System.Data.DataTable dt = new DataTable("userAndMac");
dt.Columns.Add("ME60ID", typeof(int));
dt.Columns.Add("USERNAME", typeof(string));
dt.Columns.Add("USERMAC", typeof(string));
dt.Columns.Add("INSERTDATE", typeof(DateTime));
dt.Columns.Add("UPDATETIME", typeof(DateTime));
for (int i =0; i <Count; i++)
{
dt.Rows.Add(ME60ID, alarmDataArry[i].Split(',')[0], alarmDataArry[i].Split(',')[1], DateTime.Now.ToString(), DateTime.Now.ToString());
}
mydb.insertTableToDB(dt);
}
mydb.Close();
}
catch (Exception ex)
{
saveErrorToFile(errorPath, DateTime.Now.ToString() + ex.Message + "\r\n");
//errorPath 存放程序运行错误信息
}
}
下面这个方法执行数据库操作
//这只是类的一部分,插入数据库的方法。
public void InsertTableToDB(System.Data.DataTable dt)
{
sqlCon.Open();
Invokes the stored procedure.
using (var cmd = new SqlCommand("csp_insert_user_and_mac_by_table", sqlCon))
{
cmd.CommandType = CommandType.StoredProcedure;
Adding a "structured" parameter allows you to insert tons of data with low overhead
var param = new SqlParameter("@userTable", SqlDbType.Structured) { Value = dt };
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
}
sqlCon.Close();
}
每次插入数据量不大,就1万条左右,都是秒杀的。
另外一个方法SqlBulkCopy适用于不做任何处理,批量插入原始数据。
以下部分代码来自CSDN论坛。
原来有个类之前从没有用过(也不怪,从来没有遇到过一下子插入600W条记录的性能问题),这就是神一般的SqlBulkCopy~~~
代码:
SqlBulkCopy sqlBC = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction);
sqlBC.DestinationTableName = "CSDN_Users";
DataTable dt = new DataTable("CSDN_Users");
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("UserName", typeof(string));
dt.Columns.Add("PassWord", typeof(string));
dt.Columns.Add("Email", typeof(string));
StreamReader sr = new StreamReader(@"D:\CSDN.txt");
string[] userInfo;
string readStr;
int flag = 0;
while (sr.Peek() > -1)
{
flag++;
readStr = sr.ReadLine();
userInfo = readStr.Split('#');
dt.Rows.Add(0, userInfo[0], userInfo[1], userInfo[2]);
if (flag % 100000 == 0)
{
sqlBC.WriteToServer(dt);
dt.Clear();
}
}
sqlBC.WriteToServer(dt);
dt.Dispose();
sqlBC.Close();
sr.Close();
考虑到时间跟空间的问题,觉得每次读10W条恰到好处,执行,完美,本来估计要七八个小时才能写入的1分钟就全部写入到数据库。