[[Open棟梁>https://github.com/OpenTouryoProject]] wiki
「[[Open棟梁 wiki>https://opentouryo.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-戻る
--[[機能一覧 - フレームワーク]]
--[[バッチ処理方式]]

* 目次 [#h170136f]
#contents

*概要 [#m5f315f7]
配列バインドをサポートしていないデータプロバイダでの~
大量データ処理(バッチ更新処理)の実装のために、バッチクエリ作成支援機能を提供しています。

-[[SQLUtility>https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/C%23/Frameworks/Infrastructure/Public/Db/SQLUtility.cs]]クラスの、GetInsertSQLParts、GetUpdateSQLPartsメソッドを使用すると、バッチ処理用のSQLパーツを生成できます。
-[[SQLUtility>https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Frameworks/Infrastructure/Public/Db/SQLUtility.cs]]クラスの、GetInsertSQLParts、GetUpdateSQLPartsメソッドを使用すると、バッチ処理用のSQLパーツを生成できます。
--Datatableを渡すことで複数行に渡るINSERT文、UPDATE文を生成します。

-[[BaseDam>https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/C%23/Frameworks/Infrastructure/Public/Db/BaseDam.cs]]クラス の、ExecGenerateSQLメソッドを使用すると、SQLを実行しないで、SQLのみ生成できます。
-[[BaseDam>https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Frameworks/Infrastructure/Public/Db/BaseDam.cs]]クラス の、ExecGenerateSQLメソッドを使用すると、SQLを実行しないで、SQLのみ生成できます。
--このSQLを使用して、(SQL実行のラウンドトリップを抑えた)バッチ処理を容易に実装できます。

双方とも、パタメタ数制限をクリアするために、String型パタメタは文字列展開してから実行します。

*SQLUtilityクラス [#v3733fb1]
-SQLUtilityクラスの、GetInsertSQLParts、GetUpdateSQLPartsメソッドを使用すると、バッチ処理用のSQLパーツを生成できる。
-このSQLパーツを使用して、(SQL実行のラウンド・トリップを抑えた)インサートとアップデートのバッチ処理を容易に実装できる。

**GetInsertSQLPartsメソッド [#xdd3ed2c]
***サンプル・コード [#qe0b87d9]
以下、バッチ・インサートのサンプル・コード。

 // データテーブル作成
 DataTable dt = new DataTable();
 
 ・・・データ作成コードは省略・・・
 
 // SQLパーツの生成
 // 第2・3引数は省略可能(第2の既定値はnvarchar)。
 SQLUtility su = new SQLUtility(DbEnum.DBMSType.SQLServer, "varchar", "yyyy/MM/dd");
 string[] strs = su.GetInsertSQLParts(dt);
 
 // SQLパーツの組立
 string collist = "";
 StringBuilder sb = new StringBuilder();
 
 foreach (string str in strs)
 {
   if (string.IsNullOrEmpty(collist))
   {
     collist = str;
   }
   else
   {
     sb.Append(str + ",");
   }
 }
 
 // 最後のカンマを削る。
 string temp = sb.ToString();
 temp = temp.Substring(0, temp.Length - 1);
 
 // 共通Daoでバッチ・インサート
 CmnDao cd = new CmnDao(this.GetDam());
 cd.SQLText = string.Format("INSERT INTO XXX{0} VALUES{1}", collist, temp);
 cd.ExecInsUpDel_NonQuery();

***実行されるSQL [#x73ff599]
 INSERT INTO XXX
   ([aaa],[bbb],[ccc],[ddd],[eee],[fff])
 VALUES
   (Convert(varchar,'a'),Convert(varchar,'aaa'),0xFF,0xFFFFFF,'2013/09/20',1),
   (Convert(varchar,'b'),Convert(varchar,'bbb'),0xFE,0xFEFEFE,'2013/09/20',2),
   (Convert(varchar,'c'),Convert(varchar,'ccc'),0xFD,0xFDFDFD,'2013/09/20',3)

**GetUpdateSQLPartsメソッド [#nd5c38cf]

***サンプル・コード [#gf3192d9]
以下、バッチ・アップデートのサンプル・コード。

 // データテーブル作成
 DataTable dt = new DataTable("XXX");
 
 ・・・データ作成コードは省略・・・
 
 // SQLパーツの生成
 // 第2・3引数は省略可能(第2の既定値はnvarchar)。
 SQLUtility su = new SQLUtility(DbEnum.DBMSType.SQLServer, "varchar", "yyyy/MM/dd");
 string[] strs = su.GetUpdateSQLParts(dt, new string[] { "aaa" });
 
 // SQLパーツの組立
 StringBuilder sb = new StringBuilder();
 
 foreach (string str in strs)
 {
   sb.Append("UPDATE " + dt.TableName + " " + str + ";");
 }
 
 // 共通Daoでバッチ・アップデート
 CmnDao cd = new CmnDao(this.GetDam());
 cd.SQLText = sb.ToString();
 cd.ExecInsUpDel_NonQuery();

***実行されるSQL [#y15eb127]
 UPDATE XXX
   SET [bbb] = Convert(varchar,'aaa'),[ccc] = 0xFF,[ddd] = 0xFFFFFF,[eee] = '2013/09/20',[fff] = 1
   WHERE [aaa] = Convert(varchar,'a');
 UPDATE XXX
   SET [bbb] = Convert(varchar,'bbb'),[ccc] = 0xFE,[ddd] = 0xFEFEFE,[eee] = '2013/09/20',[fff] = 2
   WHERE [aaa] = Convert(varchar,'b');
 UPDATE XXX
   SET [bbb] = Convert(varchar,'ccc'),[ccc] = 0xFD,[ddd] = 0xFDFDFD,[eee] = '2013/09/20',[fff] = 3
   WHERE [aaa] = Convert(varchar,'c');

**BaseDamクラス [#zb600a58]
-BaseDamクラスの、ExecGenerateSQLメソッドを使用すると、SQLを実行しないで、SQLのみ生成できる。
-このSQLを使用して、(SQL実行のラウンドトリップを抑えた)バッチ処理を容易に実装できる。

***ExecGenerateSQLメソッド [#v9a15412]

***サンプル・コード [#udb8f91a]
以下、バッチ・インサートのサンプル・コード(詳細は、[[RerunnableBatch_sample2>https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Samples/Bat_sample/RerunnableBatch_sample2]]を参照)。

 //Orders2テーブルに複数件まとめて追加する。
 StringBuilder sb = new StringBuilder();
 
 for (int index = 0; index < dataTable.Rows.Count; index++)
 {
   DataRow row = dataTable.Rows[index];    //1件分のデータ
 
   //todo:編集処理など
 
   // ↓DBアクセス-----------------------------------------------------
   // 自動生成Daoを生成
   DaoOrders2 dao = new DaoOrders2(this.GetDam());
 
   // パラメータを設定
   dao.PK_OrderID = row["OrderID"];
   dao.CustomerID = row["CustomerID"];
   dao.EmployeeID = row["EmployeeID"];
   ・・・
   dao.ShipRegion = row["ShipRegion"];
   dao.ShipPostalCode = row["ShipPostalCode"];
   dao.ShipCountry = row["ShipCountry"];
 
   // 自動生成Daoを実行
   sb.Append(dao.ExecGenerateSQL(
     "DaoOrders2_S1_Insert.sql", new SQLUtility(DbEnum.DBMSType.SQLServer)) + ";\r\n");
 
   // ↑DBアクセス-----------------------------------------------------
 }
 
 // 共通Daoでバッチ・インサート
 CmnDao cd = new CmnDao(this.GetDam());
 cd.SQLText = sb.ToString();
 cd.ExecInsUpDel_NonQuery();

***実行されるSQL [#d9b43e4c]

 INSERT INTO [Orders2]
   ( [OrderID], [CustomerID], [EmployeeID], [OrderDate], [RequiredDate], [ShippedDate], [ShipVia],
     [Freight], [ShipName], [ShipAddress], [ShipCity], [ShipRegion], [ShipPostalCode], [ShipCountry] )
 VALUES
   ( 10248, Convert(nvarchar,'VINET'), 5, '1996/07/04 00:00:00.000', '1996/08/01 00:00:00.000', '1996/07/16 00:00:00.000',
     3, 32.3800, Convert(nvarchar,'Vins et alcools Chevalier'), Convert(nvarchar,'59 rue de l''Abbaye'),
     Convert(nvarchar,'xxxxxx'), NULL, Convert(nvarchar,'51100'), Convert(nvarchar,'France'));
 
 INSERT INTO [Orders2]
   ( [OrderID], [CustomerID], [EmployeeID], [OrderDate], [RequiredDate], [ShippedDate], [ShipVia],
     [Freight], [ShipName], [ShipAddress], [ShipCity], [ShipRegion], [ShipPostalCode], [ShipCountry] )
 VALUES
   ( 10249, Convert(nvarchar,'TOMSP'), 6, '1996/07/05 00:00:00.000', '1996/08/16 00:00:00.000', '1996/07/10 00:00:00.000',
     1, 11.6100, Convert(nvarchar,'Toms Spezialitäten'), Convert(nvarchar,'Luisenstr. 48'),
  Convert(nvarchar,'Münster'), NULL,Convert(nvarchar,'44087'), Convert(nvarchar,'Germany'));
 
 ・・・

*参考 [#uee10eb8]
.NET用アプリケーション フレームワーク ”棟梁” 利用ガイド(ベターユース、FAQ編)~

**性能測定情報 [#fe18b665]
-Open棟梁:バッチ・サンプルの性能測定に使用した、各種リソース情報と、その測定結果。~
https://gist.github.com/daisukenishino2/5402109ba92be11f26058e163a1a770a

**利用ガイド(ベターユース、FAQ編) [#i3bdbf20]
-.NET用アプリケーション フレームワーク ”棟梁” 利用ガイド(ベターユース、FAQ編)~
https://github.com/OpenTouryoProject/OpenTouryoDocuments/blob/master/documents/1_User_Guide/ja-JP/7_User_Guide(BetterUse_and_FAQ).doc

-4章:D層に関するトピック
--4.8節:大量データ更新の実行方法
--4章:D層に関するトピック
---4.8.1項:SQLUtilityクラス	
---4.8.2項:ExecGenerateSQLメソッド

を、ご参照下さい。


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS