国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C#中海量數據的批量插入和更新

2019-11-17 03:47:59
字體:
來源:轉載
供稿:網友

對于海量數據的插入和更新,ADO.NET確實不如JDBC做到好,JDBC有統一的模型來進行批操作.使用起來
非常方便:
 PReparedStatement ps = conn.prepareStatement("insert or update arg1,args2....");
 然后你就可以
 for(int i=0;i<1000000000000000;i++){
  ps.setXXX(realArg);
  .....
  ps.addBatch();
  if(i%500==0){ //假設五百條提交一次
   ps.executeBatch();
   //clear Parame Batch
  }
 }
 ps.executeBatch();
 
這樣的操作不僅帶來極度大的性能,而且非常方便.按說,ADO.NET中,要實現這樣的功能,應該直接在Command接口中
或DataAdapter接口中提供Addbat和CommitBat的API,但ADO.NET的卻并沒有這樣簡單地實現,而是要求開發者通過
復雜的變通方法.
 對于大量的插入操作,可以利用一個空的DataTable加入要插入的行,達到一定數量提交后清空該表就行了,
實現起來并不算復雜:

 

DateTime begin = DateTime.Now;
string connectionString = ......;
using(SqlConnection conn = new SqlConnection(connectionString))...{
    conn.Open();
    SqlDataAdapter sd = new SqlDataAdapter();
    sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest", conn);
    sd.InsertCommand = new SqlCommand("insert into CurrentTest (devid,data_time,data_value) "
                    + " values (@devid,@data_time,@data_value);", conn);
    sd.InsertCommand.Parameters.Add("@devid", SqlDbType.Char, 18, "devid");
    sd.InsertCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
    sd.InsertCommand.Parameters.Add("@data_value", SqlDbType.Int, 8, "data_value");
    sd.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
    sd.UpdateBatchSize = 0;

    DataSet dataset = new DataSet();
    sd.Fill(dataset);
    Random r = new Random(1000);
    for (int i = 0; i < 100000; i++) ...{
        object[] row = ...{"DEVID"+i,DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),r.Next(1,1000) };
        dataset.Tables[0].Rows.Add(row);
        if (i % 300 == 0) ...{
            sd.Update(dataset.Tables[0]);
            dataset.Tables[0].Clear();
        }
    }
    sd.Update(dataset.Tables[0]);
    dataset.Tables[0].Clear();
    sd.Dispose();
    dataset.Dispose();
    conn.Close();
  
}
TimeSpan ts = DateTime.Now - begin;
MessageBox.Show("ts = " + ts.TotalMilliseconds);

 

對于這個測試我插入10萬條數據用時28秒.性能還算可圈可點.但是對于批量更新,搜遍全球的例子,都是把記錄Fill到DataSet中然后牧舉rows
來更新,就我這個小數據量的測試而言,把10萬條數據Fill到DataSet中已經不能工作,如果是百萬,千萬如何操作?難道一定先把要批操作的記錄
先獲取到DataSet中?也就是我要更新哪些記錄就要選查詢這些記錄?

 于是我仍然利用一個空的DataTable來加入要更新的記錄:

 sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest where 1=0", conn);
 //1=0的條件保證取一個空表.
 sd.UpdateCommand = new SqlCommand("update CurrentTest set data_time = @data_time,data_value = @data_value where devid = @devid", conn);
        sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
        sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
        sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
        sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
        sd.UpdateBatchSize = 0;

 for(int i=0;i<300;i++){
  ..............................
  dataset.Tables[0].Rows.Add(row);
 }
 sd.Update(dataset.Tables[0]);
 先更新300條試試,如果成功再循環更新所有記錄,但提示插入操作需要InsertCommand,因為一個空表然后Add Row操作,這時RowState是Added,

如果這時Update到數據庫,執行的就是插入操作而無法更新. 改成:
 for(int i=0;i<300;i++){
  ..............................

 row = {填入初始化的值};
  dataset.Tables[0].Rows.Add(row);
 }
 dataset.AcceptChanges();
 for(int i=0;i<300;i++){
  ..............................
  dataset.Tables[0].Rows[i][x] = "xxxxxxx";
  ..............................
 }
 sd.Update(dataset.Tables[0]);
 先在DataTable中插入數據,然后用AcceptChanges(),修改RowState為UnChanged,再修改表中數據希望改變UnChanged狀態,即將

DataTable從Current狀態改為Original,然后再對DataTable的Row進行更新,就能使

Update成功.但這樣做確實不方便.


 調整思路,先從數據庫中取200條(批更新的Size大小),直接得到一個Original的DataTable.

 sd.SelectCommand = new SqlCommand("select top 200 devid,data_time,data_value from CurrentTest", conn);
 DataSet dataset = new DataSet();
        sd.Fill(dataset);
 用這200個空間來放要更新的其它數據看看:
 
                    for (int i = 0; i < 100; i++)
                    {
                        dataset.Tables[0].Rows[i].BeginEdit();
                        dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
                        dataset.Tables[0].Rows[i]["data_value"] = 100;
                        dataset.Tables[0].Rows[i]["devid"] = "DEVID"+(i+10000);//更新DEVID10000到DEVID10200的記錄
                        dataset.Tables[0].Rows[i].EndEdit();
                    }
                    sd.Update(dataset.Tables[0]);
 OK,成功,哈哈.把要更新的數據不斷往這個空間填,填滿就提交,這樣更新100000條數據只要幾個循環就行了.


                  

 

DateTime begin = DateTime.Now;
            string connectionString = "";
            using(SqlConnection conn = new SqlConnection(connectionString))...{
                conn.Open();

                SqlDataAdapter sd = new SqlDataAdapter();
                sd.SelectCommand = new SqlCommand("select top 200 devid,data_time,data_value from CurrentTest", conn);

                DataSet dataset = new DataSet();
                sd.Fill(dataset);
                Random r = new Random(1000);

                sd.UpdateCommand = new SqlCommand("update CurrentTest "
                                + " set data_time = @data_time,data_value = @data_value where devid = @devid", conn);
                sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
                sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
                sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
                sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
                sd.UpdateBatchSize = 0;
                for (int count = 0; count < 100000;)
                ...{

                    for (int i = 0; i < 200; i++,count++)
                    ...{
                        dataset.Tables[0].Rows[i].BeginEdit();
                        dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
                        dataset.Tables[0].Rows[i]["data_value"] = 100;
                        dataset.Tables[0].Rows[i]["devid"] = "DEVID"+count;
                        dataset.Tables[0].Rows[i].EndEdit();
                    }
                    sd.Update(dataset.Tables[0]);
                }
 

                dataset.Tables[0].Clear();
                sd.Dispose();
                dataset.Dispose

http://m.survivalescaperooms.com/Seabiscuit/archive/2010/05/25/1743341.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 尚义县| 新民市| 赤城县| 中西区| 霍城县| 三门峡市| 武宁县| 克拉玛依市| 泾源县| 遵义市| 高雄市| 额济纳旗| 东光县| 安顺市| 阳信县| 上高县| 玛纳斯县| 来凤县| 云安县| 道真| 宁国市| 手游| 崇义县| 仲巴县| 朝阳县| 肥西县| 徐闻县| 营山县| 田阳县| 车险| 华坪县| 炉霍县| 清流县| 宾川县| 上高县| 漳平市| 铜川市| 景谷| 甘孜县| 横峰县| 通化县|