熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

.net對海量數據的插入與更新

2013-11-13 09:39:45  來源: .NET編程 
    對於海量數據的插入和更新ADONET確實不如JDBC做到好JDBC有統一的模型來進行批操作使用起來
    非常方便
    PreparedStatement ps = connprepareStatement(insert or update argargs
    然後你就可以
    for(int i=;i<;i++){
    pssetXXX(realArg)
    ……
    psaddBatch()
    if(i%==){ //假設五百條提交一次
    psexecuteBatch()
    //clear Parame Batch
    }
    }
    psexecuteBatch()
    這樣的操作不僅帶來極度大的性能而且非常方便按說ADONET中要實現這樣的功能應該直接在Command接口中
    或DataAdapter接口中提供Addbat和CommitBat的API但ADONET的卻並沒有這樣簡單地實現而是要求開發者通過


    復雜的變通方法
    對於大量的插入操作可以利用一個空的DataTable加入要插入的行達到一定數量提交後清空該表就行了
    實現起來並不算復雜
    DateTime begin = DateTimeNow;
    string connectionString = ……
    using(SqlConnection conn = new SqlConnection(connectionString))…{
    connOpen()
    SqlDataAdapter sd = new SqlDataAdapter()
    sdSelectCommand = new SqlCommand(select deviddata_timedata_value from CurrentTest conn)
    sdInsertCommand = new SqlCommand(insert into CurrentTest (deviddata_timedata_value)
    + values (@devid@data_time@data_value) conn)
    sdInsertCommandParametersAdd(@devid SqlDbTypeChar devid
    sdInsertCommandParametersAdd(@data_time SqlDbTypeChar data_time
    sdInsertCommandParametersAdd(@data_value SqlDbTypeInt data_value
    sdInsertCommandUpdatedRowSource = UpdateRowSourceNone;
    sdUpdateBatchSize = ;
    DataSet dataset = new DataSet()
    sdFill(dataset)
    Random r = new Random(
    for (int i = ; i < ; i++) …{
    object[] row = …{DEVID+iDateTimeNowToString(yyyyMMdd HH:mm:ssrNext() };
    datasetTables[]RowsAdd(row)
    if (i % == ) …{
    sdUpdate(datasetTables[])
    datasetTables[]Clear()
    }
    }
    sdUpdate(datasetTables[])
    datasetTables[]Clear()
    sdDispose()
    datasetDispose()
    connClose()
    }
    TimeSpan ts = DateTimeNow begin;
    MessageBoxShow(ts = + tsTotalMilliseconds)
    對於這個測試我插入萬條數據用時性能還算可圈可點但是對於批量更新搜遍全球的例子都是把記錄Fill到DataSet中然後牧舉rows
    來更新就我這個小數據量的測試而言萬條數據Fill到DataSet中已經不能工作如果是百萬千萬如何操作?難道一定先把要批操作的記錄
    先獲取到DataSet中?也就是我要更新哪些記錄就要選查詢這些記錄?
    於是我仍然利用一個空的DataTable來加入要更新的記錄
    sdSelectCommand = new SqlCommand(select deviddata_timedata_value from CurrentTest where = conn)
    //=的條件保證取一個空表
    sdUpdateCommand = new SqlCommand(update CurrentTest set data_time = @data_timedata_value = @data_value where devid = @devid conn)
    sdUpdateCommandParametersAdd(@data_time SqlDbTypeChar data_time
    sdUpdateCommandParametersAdd(@data_value SqlDbTypeInt data_value
    sdUpdateCommandParametersAdd(@devid SqlDbTypeChar devid
    sdUpdateCommandUpdatedRowSource = UpdateRowSourceNone;
    sdUpdateBatchSize = ;
    for(int i=;i<;i++){
    ……
    datasetTables[]RowsAdd(row)
    }
    sdUpdate(datasetTables[])
    先更新條試試如果成功再循環更新所有記錄但提示插入操作需要InsertCommand因為一個空表然後Add Row操作這時RowState是Added如果這時Update到數據庫執行的就是插入操作而無法更新
    改成
    for(int i=;i<;i++){
    ……
    row = {填入初始化的值};
    datasetTables[]RowsAdd(row)
    }
    datasetAcceptChanges()
    for(int i=;i<;i++){
    ……
    datasetTables[]Rows[i][x] = xxxxxxx;
    ……
    }
    sdUpdate(datasetTables[])
    先在DataTable中插入數據然後用AcceptChanges()修改RowState為UnChanged再修改表中數據希望改變 UnChanged狀態即將DataTable從Current狀態改為Original然後再對DataTable的Row進行更新就能使
    Update成功但這樣做確實不方便
    調整思路先從數據庫中取條(批更新的Size大小)直接得到一個Original的DataTable
    sdSelectCommand = new SqlCommand(select top deviddata_timedata_value from CurrentTest conn)
    DataSet dataset = new DataSet()
    sdFill(dataset)
    用這個空間來放要更新的其它數據看看
    for (int i = ; i < ; i++)
    {
    datasetTables[]Rows[i]BeginEdit()
    datasetTables[]Rows[i][data_time] = ::;
    datasetTables[]Rows[i][data_value] = ;
    datasetTables[]Rows[i][devid] = DEVID+(i+//更新DEVID到DEVID的記錄
    datasetTables[]Rows[i]EndEdit()
    }
    sdUpdate(datasetTables[])
    OK成功哈哈把要更新的數據不斷往這個空間填填滿就提交這樣更新條數據只要幾個循環就行了
    DateTime begin = DateTimeNow;
    string connectionString = ;
    using(SqlConnection conn = new SqlConnection(connectionString))…{
    connOpen()
    SqlDataAdapter sd = new SqlDataAdapter()
    sdSelectCommand = new SqlCommand(select top deviddata_timedata_value from CurrentTest conn)
    DataSet dataset = new DataSet()
    sdFill(dataset)
    Random r = new Random(
    sdUpdateCommand = new SqlCommand(update CurrentTest
    + set data_time = @data_timedata_value = @data_value where devid = @devid conn)
    sdUpdateCommandParametersAdd(@data_time SqlDbTypeChar data_time
    sdUpdateCommandParametersAdd(@data_value SqlDbTypeInt data_value
    sdUpdateCommandParametersAdd(@devid SqlDbTypeChar devid
    sdUpdateCommandUpdatedRowSource = UpdateRowSourceNone;
    sdUpdateBatchSize = ;
    for (int count = ; count < ;)
    …{
    for (int i = ; i < ; i++count++)
    …{
    datasetTables[]Rows[i]BeginEdit()
    datasetTables[]Rows[i][data_time] = ::;
    datasetTables[]Rows[i][data_value] = ;
    datasetTables[]Rows[i][devid] = DEVID+count;
    datasetTables[]Rows[i]EndEdit()
    }
    sdUpdate(datasetTables[])
    }
    datasetTables[]Clear()
    sdDispose()
    datasetDispose()
    connClose()
    }
    TimeSpan ts = DateTimeNow begin;
    MessageBoxShow(ts = + tsTotalMilliseconds)
    注意上面的更新操作是指在一個十萬百萬千萬條記錄中我要不斷更新其中的記錄這些要更新的記錄並不是從頭
    到尾這樣的順序只是不斷地根據條件更新任何記錄我不可能把成百上千萬記錄先Fill到ds中然後在ds中Select到
    這條記錄然後更新所以每次更新操作填入一次DataTable中提交就實現了JDBC的addBat和executeBat操作
    這個操作更新萬條用了還算勉強吧
   


From:http://tw.wingwit.com/Article/program/net/201311/11281.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.