上篇博客中介绍了批量导入Excel到数据库,其本质为将Excel转为DataTable再将DataTable 的数据取出来,一条条的插入到数据库中。下面我们介绍一种比较优化的方法:将整个DataTable导入数据库中。
首先,将Excel中的数据取出,存入DataTable中,代码如下:
[csharp] view plaincopy
///
/// 传入excel路径,转换为datatable
///
///
///
public DataTable CreateExcelDataSource(string url)
{
//定义一个DataTable数据表
DataTable dt = null;
//获得excel数据
string connetionStr = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + url + ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'";
//从Excel表的Sheet1单元格获取数据
string strSql = "select * from [Sheet1$]";
OleDbConnection oleConn = new OleDbConnection(connetionStr);
OleDbDataAdapter oleAdapter = new OleDbDataAdapter(strSql, connetionStr);
try
{
//把Excel数据填充给DataTable
dt = new DataTable();
oleAdapter.Fill(dt);
//返回数据表
return dt;
}
catch (Exception ex)
{
throw ex;
}
finally
{
oleAdapter.Dispose();
oleConn.Close();
oleConn.Dispose();
//删除上传的Excel文件(因为该文件的存在会占用多余的网站空间)
if (File.Exists(url))
{
File.Delete(url);
}
}
}
我们获得了可以存入SQLServer数据库中的DataTable了,按照之前的想法,是用循环将DataTable中的数据取出来,一条条的插入数据库;对于数据量小的数据源来说,这种做法还可以接受,但是当导入的数据相当多是,这种做法的性能是可想而知的。那么我们来看一下,如何用更优的方法解决这个问题。
批量导入代码如下:
[csharp] view plaincopy
#region 批量导入DataTable
///
批量导入DataTable
/// 批量导入DataTable
///
/// DataTable数据表
/// 表名
/// 数据列集合
/// Boolean值:true成功,false失败
public Boolean InsertTable(DataTable dt, string tableName, DataColumnCollection dtColum)
{
//打开数据库
GetConn();
try
{
//声明SqlBulkCopy ,using释放非托管资源
using (SqlBulkCopy sqlBC = new SqlBulkCopy(sqlConn))
{
//一次批量的插入的数据量
sqlBC.BatchSize = 1000;
//超时之前操作完成所允许的秒数,如果超时则事务不会提交 ,数据将回滚,所有已复制的行都会从目标表中移除
sqlBC.BulkCopyTimeout = 60;
//设置要批量写入的表
sqlBC.DestinationTableName = tableName;
for (int i = 0; i < dtColum.Count; i++)
{
sqlBC.ColumnMappings.Add(dtColum[i].ColumnName.ToString(), dtColum[i].ColumnName.ToString());
}
//批量写入
sqlBC.WriteToServer(dt);
}
return true;
}
catch
{
return false;
}
finally
{
//关闭数据库
sqlConn.Close();
}
}
#endregion
下面我们来比较一下两种导入方式的特点。
非批量导入的特点,非批量导入表结构不必相同,只需要把每一条数据提取出来,循环执行写入方法,写入数据库中;而批量导入呢?则需要表结构相同,表结构相同则可以只调用一次系统封装好的方法ColumnMappings将表中的数据导入,非常方便。当系统需要动态生成表,并且导入数据时,非批量导入实现起来就会很困难。简单来说非批量导入需要知道表结构并且多次调用同一方法;批量导入表结构需要相同,并且只调用一次方法就可以了。
两种方法各有利弊,若导入数据量很小并且不必每个字段都导入的话,非批量导入可以胜任;若导入的数据量很大,不清楚表结构,只要导入所有数据即可的话,批量导入就很有优势。具体情况具体分析选择合适的方法。