C#/SQL First of Programming memorandum


HOME > C#/SQL First

Tableのコピー方法

2014年11月4日
21:08
テーブル_Sheet1_のデータをバックアップするユーティティを作成する目的

まず、下記のコードの解説から始める。

1.テーブルBK_2にバックアップデータが存在する場合はデータを消去する必要がある。
(1) Clear()メソッド

当初、「this.confulBKDataSet.BK_2.Clear();」を用いたが、これは、メモリー中のBK_2テーブルの内容を消去するだけで、物理テーブルには影響を及ぼせない。クリアー後にテーブルの保存を試みても、保存はできない。Rowコレクションとの関連かと思われる。

momiji2.jpg

(2) Delete()メソッド

一つの解決策は、
    for (int i = 0; i < this.confulBKDataSet.BK_2.Count; i++)
    {
        this.confulBKDataSet.BK_2.Rows[i].Delete();
    }
上記のルーチンでは、500行/分のスピードで削除処理が行われ1万3千行を削除するのに約25分ほど要した。書き込みと合わせると60分の処理時間となり、実用的でない。

(3) Deleteクエリの作成

DeleteQueryAllBK2をDeleteクエリとして作成した。SQLクエリは「DELETE FROM BK_2」である。これを用いれば、約3秒でBK_2テーブルの内容が消去される。
ただし、物理テーブルのデータが消去されるので、DataSet中のBK_2テーブルは値を保持しており、このままでは、最初の1行目の書き込みで「主キー2が重複」のエラーになる。
したがって、 引き続き「this.confulBKDataSet.BK_2.Clear();」を実行してメモリー内もクリアする。

(4)ImportRow(row)メソッド

---SetAdded()メソッドでStatusを変更して---
・同一データセット内なら、SQLコマンドでコピー処理ができると考えられるが、データセットを別と設計したので、本日までは、下記のように、行単位でコピーしてテーブルBK_2にインポートを行い、Updateを行った。この場合、コピーしたままでは、UnChangedなので「 row.SetAdded();」によりStatusの変更を1行単位で行った。
・テーブル全体を一括でコピーした場合、各RowのStatusを変更する方法が不明であり、そのような方法はないのではないかと判断した。
・下記ルーチンで、約22分で1万4千行のコピーが終了する。当初の3倍の高速化を果たした。

    private void button2_Click(object sender, EventArgs e)//BK_2に保存
    {
        if (this.confulBKDataSet.BK_2.Count > 0)
        {
            this.bK_2TableAdapter.DeleteQueryAllBK2();
            this.confulBKDataSet.BK_2.Clear();
        }
        foreach (DataRow row in this.confulDataSet._Sheet1_.Rows)
        {
            row.SetAdded();//Statusの変更
            this.confulBKDataSet.BK_2.ImportRow(row);
        }
        this.Validate();
        this.bK_2BindingSource.EndEdit();
        this.bK_2TableAdapter.Update(this.confulBKDataSet.BK_2);
    }