ページ 11

DataSet/DataAdapterの仕様について

Posted: 2016年4月19日(火) 22:04
by taaasuketeeeeeeeeee
DataSet/DataAdapterの仕様についてご教授下さい。


■DataSet/DataAdapterの仕様
DataAdapter には、SELECT、UPDATE、INSERT、DELETEのSQL文が設定できます。
Fillメソッドを実行するとSELECTのSQL文の基づいてDataSetにデータを読み込みます。このときDataSetの各行には「編集なし」のマークがついています。
値を更新するとそのマークが「更新済」、削除すると「削除済」、データを追加すると「追加済」のマークに変わります。
Updateメソッドを実行すると、DataSetの各行のマークに応じて、設定してあるUPDATE、INSERT、DELETEのSQL文を実行します。


■実施したい事【概要】
DataAdapterのFillメソッドで取得したDataSet内のDataTableに対して、
挿入/更新操作をかけていき、全ての処理が終わったら、UPDATEを行う。

その際、DataTableに挿入した順番でDBへの挿入SQLが流れてほしい。


■実施したい事【詳細】

コード:

 
DataTable^ tbl;//←DataAdapterのFillメソッドで取得したDataSet内のDataTableだとします

while(10000行程度ループ){

	DataRow^ tg_row = tbl->Rows->Find(ループ毎に変わる値);

	if( static_cast<DataRow^>(tg_row)==nullptr){
		DataRow^ row = tbl->NewRow();
		row["hogehoge"] = ループ毎に変わる値;
		tbl->Rows->Add(row);//←★★★★★★初期挿入★★★★★★★
	}
	else{
		row["hogehoge"] = ループ毎に変わる値;
	}

}

上記のソースで5000行のレコードが出来たと仮定します。
※つまり"ループ毎に変わる値"の重複が半分あったということ

この状態でUPDATEを行うと、
なぜか、初期挿入した順番通りにinsert文が発行されません。
※DB上で見ると順番がごちゃまぜです

■質問①
なぜ、初期挿入した順番通りにinsert文が発行されないのでしょうか?
tbl->Rows->Findで取得したレコードの値を変更すると順番が変更になってしまうのでしょうか?

■質問②
初期挿入した順番にinsert文が発行されようにするには、
どの様にしたら良いでしょうか?
解決策をご教授下さい。

Re: DataSet/DataAdapterの仕様について

Posted: 2016年4月22日(金) 21:37
by YuO
とりあえず,.NET Frameworkの話であることを前提として。

DataAdapter.UpdateのMSDNを読む限り,DataTableのPrimaryKeyで指定されている順序でInsertが走りそうですが……。
PrimaryKeyは正しく設定され,さらに挿入したDataRowのPrimaryKeyに対応する値は挿入順になっていますか。

根本的にはRDBは非順序集合ですので,RDBに挿入順序を保持することを求めるのが間違っている気もします。
挿入の順序が問題になるのであれば,自分で毎回INSERTを書いて呼び出せばよいと思いますし,取得したデータの順序が問題ならSELECTにちゃんとORDER BYを付ければ解決しそうですが……。
オフトピック
最近はDataSetではなくDapperの薄いORM層しか使っていない上,DataSetも直後にオブジェクトに詰め替えていたので,DataAdapterのUpdateでの順序なんて気にしたことがなかった……。