
多種方法實現(xiàn)Excel批量導(dǎo)入數(shù)據(jù)庫
Excel批量導(dǎo)入數(shù)據(jù)庫是用到批量導(dǎo)入系統(tǒng)的一個難題,特別是需要批量導(dǎo)入的Excel表比較復(fù)雜,或者這張Excel表需要多表插入的時候,批量導(dǎo)入就變得復(fù)雜起來。其實了解了批量導(dǎo)入的原理之后,批量導(dǎo)入也就不再復(fù)雜。
批量導(dǎo)入的原理其實很簡單,首先下載模板,填入信息后進(jìn)行導(dǎo)入;然后讀取Excel文件的路徑,上傳Excel文件,如果需要保存的話;其次進(jìn)行數(shù)據(jù)轉(zhuǎn)化,例如將Excel表的信息轉(zhuǎn)化成DataTable;最后將DataTable導(dǎo)入到數(shù)據(jù)庫中。知道了批量導(dǎo)入的原理之后,就應(yīng)該一步一步的解決問題,剩下的就是代碼了。
一中考評系統(tǒng)中,后臺管理需要導(dǎo)入比較多,最主要的就是導(dǎo)入教職工。因為這個考評系統(tǒng)本來就是用于教師和教師之間測評,所以教職工信息肯定需要后臺管理員導(dǎo)入,而不是一條一條添加。一個學(xué)校兩百多個教師,一個一個添加就太不為用戶考慮了。
一中考評的導(dǎo)入首先用的是SqlBulkCopy的批量導(dǎo)入,因為這種方式是性能比較不錯的一種方式,有人進(jìn)行測試,導(dǎo)入68萬條數(shù)據(jù)大概需要53秒,所以就果斷直接采用的這種方式。我們是用它導(dǎo)入DataTable,就是先把Excel轉(zhuǎn)化成DataTable,然后直接用SqlBulkCopy向數(shù)據(jù)庫中寫入DataTable。代碼如下:
[csharp] view plain copy
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"> /// <summary>
/// 批量導(dǎo)入DataTable
/// </summary>
/// <param name="strDatabaseName">配置文件key</param>
/// <param name="dt">datatable名稱</param>
/// <param name="tableName">表名稱</param>
/// <param name="dtColum">所有列(dt.columns)</param>
/// <returns>返回true,or false</returns>
public Boolean InsertTable(string strDatabaseName, DataTable dt, string tableName, DataColumnCollection dtColum)
{
using (TransactionScope scope1 = new TransactionScope(TransactionScopeOption.Required))
{
using (SqlBulkCopy sqlBC = new SqlBulkCopy(
GetConnection(strDatabaseName).ConnectionString, SqlBulkCopyOptions.KeepIdentity))
{
sqlBC.BatchSize = 1000;
sqlBC.DestinationTableName = tableName;
// Write from the source to the destination.
// This should fail with a duplicate key error.
for (int i = 0; i < dtColum.Count; i++)
{
sqlBC.ColumnMappings.Add(dtColum[i].ColumnName.ToString(), dtColum[i].ColumnName.ToString());
}
try
{
//批量寫入
sqlBC.WriteToServer(dt);
scope1.Complete();
return true;
}
catch
{
throw new Exception("導(dǎo)入數(shù)據(jù)失?。?);
}
}
}
}</span></span>
但是這種導(dǎo)入方法有兩個缺陷,一個是數(shù)據(jù)類型轉(zhuǎn)化為Guid不成功,一個是導(dǎo)入數(shù)據(jù)庫時列亂序。而且SqlBulkCopy做批量導(dǎo)入的時候,需要保證導(dǎo)入的DataTable的順序和數(shù)據(jù)庫表是一樣的,這樣就給復(fù)雜的Excel表的插入造成了一定的困難。簡單的導(dǎo)入Excel文件,可以在設(shè)置模板的時候,就把順序和數(shù)據(jù)庫表對應(yīng)好。
然后我們就采取了另外一種方式,那就是拼接Sql語句,直接用sql語句導(dǎo)入。其實對于大批量導(dǎo)入數(shù)據(jù),sql語句執(zhí)行起來比較慢,特別是數(shù)據(jù)量在十萬條以上的。但是對于小數(shù)據(jù)量,就比如我們系統(tǒng),需要導(dǎo)入幾百個教師信息,改動數(shù)據(jù)庫字段類型對系統(tǒng)其它地方改動太大,除非在設(shè)計數(shù)據(jù)庫的時候就能注意到這個問題。對于我們這種情況,還是改導(dǎo)入方式比較方便,于是就采用了拼接sql語句。
因為DataTable已經(jīng)轉(zhuǎn)化完成,所以我們可以直接循環(huán)DataTable的行去拼接sql語句:
[csharp] view plain copy
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"> /// <summary>
/// 導(dǎo)入Excel數(shù)據(jù)至DB的方法
/// </summary>
/// <param name="strPath">導(dǎo)入Excel文件全路徑</param>
/// <param name="strXMLName">相關(guān)XML名稱</param>
/// <param name="dicDefaultColumn">默認(rèn)列數(shù)據(jù)</param>
/// <param name="strDBKey">數(shù)據(jù)庫連接WebConfig配置鍵值</param>
/// <returns>過程中出現(xiàn)的問題數(shù)據(jù)</returns>
public Dictionary<int, DataTable> ImportExcel(string strPath, string strXMLName, Dictionary<string, string> dicDefaultColumn, string strDBKey)
{
//得到導(dǎo)入目標(biāo)表的DataTable
Dictionary<int, DataTable> dicTargetTable = this.GetImportTable(strPath, strXMLName, dicDefaultColumn, strDBKey);
//得到導(dǎo)入第三張表的DataTable
Dictionary<int, DataTable> dicThirdTable = this.GetThirdTable();
//得到過程中出現(xiàn)的問題表
Dictionary<int, DataTable> dicErrorTable = this.GetErrorTable();
//數(shù)據(jù)庫連接字符串,讀配置文件
SQLHelper sqlHelper = new SQLHelper("YzEvaluationSystemEntities", true);
//執(zhí)行隱式事務(wù)
try
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
for (int intTableIndex = 0; intTableIndex < dicTargetTable.Count; intTableIndex++)
{
if (dicTargetTable[intTableIndex].Rows.Count > 0)
{
DataTable dtTarget = dicTargetTable[intTableIndex];
StringBuilder sbSql = new StringBuilder();
for (int i = 0; i < dtTarget.Rows.Count; i++)
{
//sql語句拼接
sbSql.Append("insert into ").Append(dtTarget.TableName.ToString()).Append("(ID,StaffName,StaffPassword,StaffID,Sex,IdentityCard,Subject,WorkDate,EngageDate,jobQualification,DivisionID,SeriesID,IsUsed) values (");
sbSql.Append("'" + dtTarget.Rows[i]["ID"] + "',")
.Append("'" + dtTarget.Rows[i]["StaffName"] + "',")
.Append("'" + dtTarget.Rows[i]["StaffPassword"] + "',")
.Append("'" + dtTarget.Rows[i]["StaffID"] + "',")
.Append("'" + dtTarget.Rows[i]["Sex"] + "',")
.Append("'" + dtTarget.Rows[i]["IdentityCard"] + "',")
.Append("'" + dtTarget.Rows[i]["Subject"] + "',")
.Append("'" + dtTarget.Rows[i]["WorkDate"] + "',")
.Append("'" + dtTarget.Rows[i]["EngageDate"] + "',")
.Append("'" + dtTarget.Rows[i]["jobQualification"] + "',")
.Append("'" + dtTarget.Rows[i]["DivisionID"] + "',")
.Append("'" + dtTarget.Rows[i]["SeriesID"] + "',")
.Append("'" + dtTarget.Rows[i]["IsUsed"] + "' ")
.Append(")");
}
//往SQLHelper里面提交數(shù)據(jù)
int flag = sqlHelper.ExecuteNonQuery(sbSql.ToString(), CommandType.Text);
}
}
scope.Complete();
}
}
catch (Exception e)
{
throw new Exception(e.Message);
}
Boolean bolIsExistErrorData = false;
foreach (int intErrorTableIndex in dicErrorTable.Keys)
{
if (dicErrorTable[intErrorTableIndex].Rows.Count > 1)
{
bolIsExistErrorData = true;
}
}
if (bolIsExistErrorData)
{
return dicErrorTable;
}
return null;
}</span></span>
這樣循環(huán)拼接其實是拼接了多條insert語句,DataTable每一行數(shù)據(jù)都是一個insert語句,多條一起執(zhí)行,就實現(xiàn)了Excel的批量導(dǎo)入。
總結(jié)
什么是好的系統(tǒng),并不是說技術(shù)用最新的,架構(gòu)用最好的,最后系統(tǒng)一定是好的。就像貪心算法一樣,每一個子問題都用最優(yōu),最后結(jié)果不一定最優(yōu),做系統(tǒng)也是一樣。只有做出最適合客戶需求,系統(tǒng)最適合客戶需求就好。還有一點,就是一切要以數(shù)據(jù)說話,做系統(tǒng)需要真實數(shù)據(jù)去測試,測試不同方法的反應(yīng)時間,最后選擇一個最合適的方法。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
訓(xùn)練與驗證損失驟升:機(jī)器學(xué)習(xí)訓(xùn)練中的異常診斷與解決方案 在機(jī)器學(xué)習(xí)模型訓(xùn)練過程中,“損失曲線” 是反映模型學(xué)習(xí)狀態(tài)的核心指 ...
2025-09-19解析 DataHub 與 Kafka:數(shù)據(jù)生態(tài)中兩類核心工具的差異與協(xié)同 在數(shù)字化轉(zhuǎn)型加速的今天,企業(yè)對數(shù)據(jù)的需求已從 “存儲” 轉(zhuǎn)向 “ ...
2025-09-19CDA 數(shù)據(jù)分析師:讓統(tǒng)計基本概念成為業(yè)務(wù)決策的底層邏輯 統(tǒng)計基本概念是商業(yè)數(shù)據(jù)分析的 “基礎(chǔ)語言”—— 從描述數(shù)據(jù)分布的 “均 ...
2025-09-19CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-19SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗與 t 檢驗:差異、適用場景與實踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計學(xué)領(lǐng)域,假設(shè)檢驗是驗證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點數(shù)據(jù)的科學(xué)計數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點數(shù)據(jù)時的科學(xué)計數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計” 與 “用戶體驗 ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11