小弟新手程式員一枚,代碼技術和文章水平均不才。所寫文章均為對自己所寫所學代碼的簡單記錄,可能對於老手程式員營養價值不高,望莫見怪。 我工作上有個需求:從某處API介面上獲取數據(大約1W條而已)並插入到資料庫中。 樓主剛畢業菜鳥,沒做過批量插入操作。藉助baidu搜索得知SqlBulkCopy可以實 ...
小弟新手程式員一枚,代碼技術和文章水平均不才。所寫文章均為對自己所寫所學代碼的簡單記錄,可能對於老手程式員營養價值不高,望莫見怪。
我工作上有個需求:從某處API介面上獲取數據(大約1W條而已)並插入到資料庫中。
樓主剛畢業菜鳥,沒做過批量插入操作。藉助baidu搜索得知SqlBulkCopy可以實現。SqlBulkCopy相關的原理,我現在還沒瞭解就不擺弄了,以後補上!
(不要問為什麼不用google,公司內網就連msdn.microsoft.com都不給上!另外我公司是開發C#/.NET的,不是JAVA。 )
首先,要從介面獲取數據自然少不了發送請求,將XML格式的數據放入記憶體表DataTable中。
#region 發送HTTP獲取數據 /// <summary> /// 發送HTTP獲取數據 /// </summary> /// <param name="url">介面地址</param> /// <param name="method">介面方法</param> /// <returns></returns> public DataTable GetDataAsTabel(string url, string method) { DataSet ds = new System.Data.DataSet(); try { HttpWebRequest request = HttpWebRequest.Create(url + method) as HttpWebRequest; request.Method = "GET"; WebResponse response = request.GetResponse(); Stream stream = response.GetResponseStream(); string str = ""; using (StreamReader sr = new StreamReader(stream)) { str = sr.ReadToEnd(); } str.Trim(); ds.ReadXml(new StringReader(str), System.Data.XmlReadMode.Auto); return ds.Tables[0]; } catch (Exception ex) { MessageBox.Show("GetDataAsTabel方法出錯:" + ex.Message); return null; } } #endregion
其次,使用SqlBulkCopy類把數據放資料庫。SqlBulkCopy.WriteToServer()提供了4種重載方式,如下:
public void WriteToServer(DataRow[] rows);
public void WriteToServer(DataTable table);
public void WriteToServer(IDataReader reader);
public void WriteToServer(DataTable table, DataRowState rowState);
顯然第二種最簡單粗暴,大家都喜歡的。也就是上面的代碼為什麼要返回DataTable了。在新建SqlBulkCopy實例時,可以由SqlBulkCopyOptions來設置插入時的檢查約束、鎖表、觸發器、每批次事務等操作。sqlBC.DestinationTableName是DB中要插入數據的表名。sqlBC.BatchSize是每一批次放入資料庫的數據量。
預設情況下,SqlBulkCopy會認為源數據DataTable的列與目標表的列是一一對應的,一旦兩者有所不同(列數或列名不一致)則會插入失敗並報錯。所以,我們需要用public SqlBulkCopyColumnMapping Add(string sourceColumn, string destinationColumn)來添加源列名與目標列名的對應關係。數據格式不用做匹配,SqlBulkCopy會幫忙轉換。當然,用非時間格式的string轉換成DateTime這種情況毫無疑問的報錯。最後,qlBC.WriteToServer()收工。
#region 把數據寫入資料庫 /// <summary> /// 把數據寫入資料庫 /// </summary> /// <param name="tableName">資料庫表名</param> /// <param name="dt">數據</param> /// <returns></returns> public bool WriteToServer(string tableName,DataTable dt) { bool execResult = false; SqlConnection sqlCon = new SqlConnection(SqlConnectionString); sqlCon.Open(); SqlTransaction sqlTran = sqlCon.BeginTransaction(); // 開始事務 SqlBulkCopy sqlBC = new SqlBulkCopy(sqlCon, SqlBulkCopyOptions.Default, sqlTran); sqlBC.DestinationTableName = tableName; sqlBC.BatchSize = 10000; for (int i = 0; i < dt.Columns.Count; i++) { sqlBC.ColumnMappings.Add(dt.Columns[i].ColumnName,dt.Columns[i].ColumnName); } try { sqlBC.WriteToServer(dt); sqlTran.Commit(); execResult = true; } catch (Exception ex) { execResult = false; sqlTran.Rollback(); MessageBox.Show("資料庫錯誤:" + ex.Message); } finally { sqlBC.Close(); sqlCon.Close(); } return execResult; } #endregion
相關文章:http://www.cnblogs.com/zfanlong1314/archive/2013/02/05/2892998.html
既是推薦也是我自己的mark。