C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: データ取得済みDataTableからの絞り込み


(過去ログ 93 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■55685 / inTopicNo.1)  データ取得済みDataTableからの絞り込み
  
□投稿者/ asuka (19回)-(2010/12/09(Thu) 14:36:52)

分類:[.NET 全般] 

お世話になっております。

スレッド[55621]から立て続けで申し訳ありませんが、DataTableについてご教授願いします。

SQLサーバ上のAテーブルから一度絞り込んで取得したDataTableから、

更に絞りこみをかけることは出来るのでしょうか?

---
Aテーブル
BuNo, Data1, Data2, UpDateTime
1, 'data1','data2', 'YYYY/MM/DD'
2
2
3
3
3

---
日に一度実行される常駐プログラムからSQLサーバのデータをAccessMDBへ取りこんでいます。
最初にUpDateTimeが本日以上のデータをDataTableに格納しております。
このデータをAccessMDB(YYYYMMDD_x.mdb)へインサートしたいのですが、膨大なデータのため、
Accessが1.5Gになったらファイル名の最後(x)をインクリメントして別ファイルへ書込みます。
(Accessのファイル制限約2G)

この際、処理を重複することがあるBuNoごとに処理したい(ファイルサイズをBuNoごとにチェック)ので、
一度日付で絞り込みをかけたDataTableから、再度BuNoで絞り込みたいと考えています。

1.日付で絞り込みんだDataTable
SqlDataAdapter adapter = new SqlDataAdapter();
DataTable dataTable = new DataTable();
adapter.SelectCommand = new SqlCommand("日付で絞りこみのSQLクエリ", connection);
nNumOfBuNo = adapter.Fill(dataTable);

2.
for ( int i = 1; i <= nNumOfBuNo; i++ ) //iはBuNoごとの処理
{
 //ここで更にBuNoで絞りこんで、該当するBuNoをMDBへインサートしたい
 //nNumOfBuNoは日付で絞りこみ済みのBuNoの総数

}

1.にて一度絞りこんだDataTableから該当するBuNo(複数時あり)のデータのみを取得することは可能でしょうか?
可能な場合、例えばi=3の場合に該当するデータは3つありますが、
DataTableからこの3データをどのように再絞り込みするのでしょうか?
(可能であれば取得したデータの任意のデータを表示する方法も御指南頂けると幸いです。)

無理である場合、2の処理で、再び1での処理のように毎回データを取得しなおす方法しかありませんでしょうか?
またその際、パフォーマンスの心配などがありましたら教えて頂けると助かります。

---
VS2010
.NetFramework2.0
Win32 C#プログラムからのみ実装

引用返信 編集キー/
■55686 / inTopicNo.2)  Re[1]: データ取得済みDataTableからの絞り込み
□投稿者/ aetos (350回)-(2010/12/09(Thu) 14:38:59)
No55685 (asuka さん) に返信
> お世話になっております。
>
> スレッド[55621]から立て続けで申し訳ありませんが、DataTableについてご教授願いします。
>
> SQLサーバ上のAテーブルから一度絞り込んで取得したDataTableから、
>
> 更に絞りこみをかけることは出来るのでしょうか?

DataTable.Select か DataView を使えばできます。
引用返信 編集キー/
■55688 / inTopicNo.3)  Re[2]: データ取得済みDataTableからの絞り込み
□投稿者/ マサヤ (184回)-(2010/12/09(Thu) 14:52:06)
http://msdn.microsoft.com/ja-jp/library/det4aw50%28v=VS.80%29.aspx
ここに書かれてるのでできませんか?
引用返信 編集キー/
■55689 / inTopicNo.4)  Re[1]: データ取得済みDataTableからの絞り込み
□投稿者/ shu (267回)-(2010/12/09(Thu) 14:58:15)
No55685 (asuka さん) に返信

> 2.
> for ( int i = 1; i <= nNumOfBuNo; i++ ) //iはBuNoごとの処理
> {
>  //ここで更にBuNoで絞りこんで、該当するBuNoをMDBへインサートしたい
>  //nNumOfBuNoは日付で絞りこみ済みのBuNoの総数
>
> }
>
このforループですべてのBunNoについて処理するのならDBからの取得時に並び替えておいて
DataTableのデータを順に読んでBunNoの変わり目を判断しつつ処理をすればいい気がするのですが
それは出来ませんか?
引用返信 編集キー/
■55691 / inTopicNo.5)  Re[2]: データ取得済みDataTableからの絞り込み
□投稿者/ マサヤ (186回)-(2010/12/09(Thu) 15:10:34)
>日付で絞りこみのSQLクエリ
なのですが、ここで日付の絞り込みとBuNoでの絞り込み、さらにInsertをできるのではないでしょうか?
そうしたらDataTableを使用しなくて済みます。
Insert Selectって駄目なんでしょうか?
引用返信 編集キー/
■55692 / inTopicNo.6)  Re[1]: データ取得済みDataTableからの絞り込み
□投稿者/ shu (268回)-(2010/12/09(Thu) 15:28:50)
No55685 (asuka さん) に返信

> (可能であれば取得したデータの任意のデータを表示する方法も御指南頂けると幸いです。)

DataTable tblData 〜



Rowsを使用する方法:
DataRow row = tblData.Rows[<index>];

Selectを使用する方法:
DataRow rows[] = tblData.Select(条件,並び替え);
DataRow row = rows[<index>];

項目値の取得:
row[項目名文字列] => DBNull.Valueまたは入っている値が返ってくるので適当にキャスト
row[<項目Index>] でも可



引用返信 編集キー/
■55698 / inTopicNo.7)  Re[2]: データ取得済みDataTableからの絞り込み
□投稿者/ asuka (20回)-(2010/12/09(Thu) 16:51:33)
お返事頂き恐縮です。

DataTable.Select か DataViewを理解すれば明るい未来が待っているような気がしてきました。

ありがとうございます。

頂いたレスを何度も何度も見直しながら、ご提示頂いたURLとにらめっこしております。

初歩的な質問で申し訳ありませんが、日付の後に絞り込んだ後、
DataRow[] rows = dataTable.Select("BuNo = 3");

ここでデバッグすると、例にも記載させて頂いたテーブルの通り、

rowsには0〜2の3配列が出来、中にデータが格納されているのをデバッグで確かめました。



このデータをMDBへインサートする方法ですが、MDBの全データをSqlDataAdapter(変数名sqlDAMDB)でもっておき、取得したrowsをアップデートすればよろしいでしょうか?
sqlDAMDB.Update(rows2[3])
実装してみた結果アップデートがされていない模様でした。
お気づきの点がありましたらご指摘頂けると幸いです。


引用返信 編集キー/
■55702 / inTopicNo.8)  Re[3]: データ取得済みDataTableからの絞り込み
□投稿者/ asuka (21回)-(2010/12/09(Thu) 18:21:00)
2010/12/09(Thu) 19:26:09 編集(投稿者)
2010/12/09(Thu) 19:25:09 編集(投稿者)

ばらばらとすみません。

> マサヤさま
BuNoが、例えばBuNo=1のものについて言いますと、1が100個くらいあり、

BuNo=2も100個、BuNo=3も100個・・・となるので、BuNoごとに毎回アクセスのサイズを取得して、

1.5Gを超えているようなら別ファイルを生成しているので恐らく一気には絞り込めないかと思っています。


>shuさま
前件から引続きありがとうございます。

sqlDAMDB.Update(rows2[3])ではなくsqlDAMDB.Update(rows2)でした。



処理開始(BuNoごとのループ)前にSQLサーバのAテーブルの全情報を取得しています。
DataTable dtSQLA = new DataTable();
oleDBCmdSQL = new OleDbCommand("SELECT * FROM A", connSQL);
oleDBDASQLA.SelectCommand = oleDBCmdSQL;
oleDBDASQLA.Fill(dtSQLA);

BuNo=1の時の処理で必ずテーブルをドロップしてクリエイト(SELECT INTO)しているので、
この時点でAccessMDBのAテーブルの全情報を取得しています。
oleDBCmdMDB = new OleDbCommand("SELECT * FROM A", conn);
oleDBDAMDBA.SelectCommand = oleDBCmdMDB;
oleDBDAMDBA.Fill(dtMDBA); //DataTable dtMDBA = new DataTable();

BuNo=2以降でSQLサーバから取得したDataTableをBuNoで絞っています。
DataRow[] rows = dtSQLA.Select("bukken_no = " + arrBukkenNo[i]);

絞ったrowsをAccessMDBへインサート(というべきでしょうか?)しています。(しているつもり)
nUpdate = dtMDBA.Update(rows);

結果、nUpdate =0 件が返ってきて更新されていません。

デバッグで確認したことは、dtSQLA、dtMDBA、rowsの値が取れていることです。
(dtSQLA、dtMDBAはデータがどこの配列か確認出来なかったので件数で確認。)



何かお心当たりがあればアドバイス頂けると幸いです。
(頻繁に更新して申し訳ありません。)


引用返信 編集キー/
■55709 / inTopicNo.9)  Re[4]: データ取得済みDataTableからの絞り込み
□投稿者/ shu (272回)-(2010/12/09(Thu) 21:25:55)
No55702 (asuka さん) に返信

DataAdapterを使った追加・更新は

DataAdapter Da
DataTable tbl

として

Da.Fill(tbl)
row = tbl.Rows(〜)
rowの編集
または
row = tbl.NewRow
tbl.Rows.Add(row)
rowの編集

をして
Da.Update(tbl)
のような感じになります。

追加のみと分かっているならMDBのテーブルから全レコードを取得する必要はありません。
テーブルの型情報だけ取得出来ていればよいです。

引用返信 編集キー/
■55710 / inTopicNo.10)  Re[5]: データ取得済みDataTableからの絞り込み
□投稿者/ asuka (22回)-(2010/12/09(Thu) 21:58:02)
shuさま

何度も申しわけありません。m(__)m

> または
> row = tbl.NewRow
> tbl.Rows.Add(row)
> rowの編集
> をして
> Da.Update(tbl)
> のような感じになります。

「rowの編集」というのは、存在する行にちなんだ列数分データを手動で設定しなければならないのでしょうか?
Ex.
row[i][0]=1
row[i][1]="data1"
row[i][2]="data2"
row[i][3]="YYYYMMDD"

今回はMDBへSQLサーバで取得したデータをそのまま入るのが主旨でしたので、
DataRow[] dataRows = dtSQLA.Select("BuNo = " + i);
DataRow dataRowsTemp;
//int nCntRows = 0;
foreach (DataRow dr in dataRows)
{
 dataRowsTemp = dtMDBA.NewRow();
 //行追加
 dtMDBA.Rows.Add(dataRowsTemp);
 //rowの編集をしなくてはだめ?
 //更新
 oleDBDAMDBA.Update(dtMDBA);
 //nCntRows++;
}

のように、可能であれば「行の追加」の前にカウンタを設けて(カウンタの更新はコメントアウトの位置)
dataRowsTemp = dataRows[nCntRows];
としてAdd後、Updateとしてそのままコピーしたかったのですが、これはダメでした。
→この行は既に別のテーブルに属しています。

DataTableにImportRowというのを見つけましたので、これで何とかならなかもう少し粘ってみたいと思います。

いつもありがとうございます。
引用返信 編集キー/
■55712 / inTopicNo.11)  Re[6]: データ取得済みDataTableからの絞り込み
□投稿者/ shu (273回)-(2010/12/09(Thu) 22:34:27)
No55710 (asuka さん) に返信
>
> DataTableにImportRowというのを見つけましたので、これで何とかならなかもう少し粘ってみたいと思います。
>
ImportRowはNewRowと同じ事になるので多分登録出来るかと思います。項目名が同じならいけるでしょう。
引用返信 編集キー/
■55720 / inTopicNo.12)  Re[7]: データ取得済みDataTableからの絞り込み
□投稿者/ asuka (23回)-(2010/12/10(Fri) 13:59:47)
解決致しましたのでご報告に参りました。

アドバイス頂いた方には大変感謝しております。

ありがとうございました。

とくにshuさんには最後まで面倒見て頂き感謝多謝です。



いくつかポイントがありましたのでメモしておきます。

●データ追加時にInsertCommandを指定するよう例外が発生
→コピー先のデータアダプタをコマンドビルダーを用いて生成することにより、
データアダプタの「SelectCommand」を基にして「InsertCommand」「UpdateCommand」「DeleteCommand」
に自動でSQLを設定してくれるのでエラーを回避出来る
http://oshiete.goo.ne.jp/qa/1304483.html
OleDbDataAdapter oleDBDAMDBA = new OleDbDataAdapter("SELECT * FROM A", connMDB);
OleDbCommandBuilder oleDBCmdBuilder = new OleDbCommandBuilder(oleDBDAMDBA);
oleDBDAMDBA.Fill(dtMDBA);

●DataTableにImportRowするときの注意
DataTableにImportRowで別のDataTableからデータを1行ずつ突っ込む場合、
事前に「テーブルごとまるまる突っ込む」といった処理が行われていれば良いのだが、
そうでない場合はうまくいかない。
理由は、受け入れ側のDataTableに、データ構造等の情報が全く無いから。
http://d.hatena.ne.jp/frontline/20070215/p2
→今回は一回目の処理時(BuNo=1)のときにMDBのテーブルをドロップしてSELECT INTOで作成しているため、
SQLサーバ側とのスキーマが異なりデータが挿入出来なかった模様。(本当かなぁ・・・)

→回避策 DataRowを複写してDataTableに追加

●DataRowを複写してDataTableに追加
http://www1.yel.m-net.ne.jp/oss/Tips/ADO/Tips_03004.htm

→複数レコードセットがある場合は更にデータ数分ループでラップ
int nCntRows = 0;
DataRow[] dataRows;
DataRow[] dataRows = dtSQLA.Select("BNuo = " + [i]);
foreach (DataRow dr in dataRows)
{
 dataRowsTemp = dtMDBA.NewRow();
 foreach (DataColumn col in dtMDBA.Columns)
 {
  //自動インクリメント列は除く
  if (col.AutoIncrement)
   continue;
  dataRowsTemp[col.Ordinal] = dataRows[nCntRows][col.Ordinal];
 }
 nCntRows++;
 dtMDBA.Rows.Add(dataRowsTemp);
}
oleDBDAMDBA.Update(dtMDBA);



どなたかのお役に立てれば幸いです。

今日もたくさんの愛を☆

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -