「Open棟梁 wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
名前バインドにのみ対応しています。このため、どのデータプロバイダであっても、順番バインドをサポートしません。
public class GenDaoParam { public object Value; public object DbType; public int Size; public ParameterDirection Direction; }
ストアド プロシジャでも動的パラメタライズド・クエリ機能を使用できます。
ストアド プロシージャの実行も可能である。
/// <summary>「sp_help」ストアドプロシージャを実行する。</summary> /// <param name="objectName">「sp_help」ストアドプロシージャの「objname」パラメタに指定する文字列</param> /// <param name="ds">「sp_help」ストアドプロシージャが返す結果セット(複数返る)</param> /// <returns>「sp_help」ストアドプロシージャの戻り値(成功:「」、失敗:「」)</returns> public int sp_help(string objectName, out DataSet ds) { // ストアドプロシージャを指定する。 this.SetSqlByCommand("sp_help", CommandType.StoredProcedure); // 引数パラメタを設定する。 this.SetParameter("objname", objectName); // 戻り値パラメタを設定する。 this.SetParameter("ret", null, null, -1, ParameterDirection.ReturnValue); // ストアドプロシージャを実行し、データリーダを戻す。 SqlDataReader drd = (SqlDataReader)this.ExecSelect_DR(); // 結果セットを取得する ds = new DataSet(); // 結果セットは複数取得可能 do { // DataTableを生成 DataTable dt = new DataTable(); // データリーダから結果をロード dt.Load(drd); // DataTableを格納 ds.Tables.Add(dt); } while (!drd.IsClosed); // データリーダを閉じる。 drd.Close(); // ストアドプロシージャの戻り値パラメタの値を取得。 return (int)((DamSqlSvr)this.GetDam()).DamSqlCommand.Parameters["ret"].Value; }
B層ベースクラス2の例外処理をカスタマイズして、 リトライ対象例外を業務例外に振り替え、P層に正常系の戻り値が戻るようにします。
Dim sr As New System.IO.StreamReader("C:\temp\input.txt",System.Text.Encoding.Default) Dim ts as String ts = sr.ReadToEnd() sr.Close() Dim fs As New System.IO.FileStream("C:\temp\input.gif",System.IO.FileMode.Open,System.IO.FileAccess.Read) Dim bs(fs.Length) As Byte fs.Read(bs,0,fs.Length) cmd.CommandText = "INSERT INTO TLOB(NO,TEXT,IMG) VALUES(:v1 ,:v2 ,:v3) " cmd.CommandType = CommandType.Text Dim p1 As New OracleParameter() p1.OracleDbType = OracleDbType.Decimal p1.Value = 3 cmd.Parameters.Add(p1) Dim p2 As New OracleParameter() p2.OracleDbType = OracleDbType.Clob p2.Value = ts cmd.Parameters.Add(p2) Dim p3 As New OracleParameter() p3.OracleDbType = OracleDbType.Blob p3.Value = bs cmd.Parameters.Add(p3) cmd.ExecuteNonQuery() tx.Commit()
cmd.CommandText = "SELECT id, clob_column FROM clob_content WHERE id = 1"; OracleDataReader reader = cmd.ExecuteReader(); reader.Read();
cmd.CommandText = "SELECT XXXX FROM YYYY FOR UPDATE"; reader = cmd.ExecuteReader(); reader.Read(); OracleClob clob = reader.GetOracleClob(0); clob.Append(ending.ToCharArray(), 0, ending.Length); txn.Commit();
共通のコマンド タイムアウト値をconfigファイルに設定できます。
100,000件 selectの処理を調査したところ、
単体でのSQL実行(SQL Server上でのselect文発行)のレスポンスが1秒程度で、
データ取得後のDataTable?へのデータ設定で、8秒を使用しているようでした。
Datatableは少々重いので、大量データには不向きかもしれません。
DataTable?ではなくDataReader?を使用するAPIを使用すると良いかと思います。
自動生成Daoで使用する場合は、テンプレートを修正すればいけると思います。
https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/files/tools/DGenTemplates/DaoTemplate2.cs#L347
ODP.NET配列バインドの場合、
以下、ODP.NETのサンプル(自作Daoクラス)。
// SQLを設定 this.SetSqlByCommand("INSERT INTO XXX(AAA, BBB, CCC) VALUES(:P1, :P2, :P3);"); // ODP.NETの配列バインドの場合は、ArrayBindCountを指定 ((DamOraOdp)this._dam).DamOracleCommand.ArrayBindCount = temp.Length; // 配列データを作成 object[] temp1 = new string[] { "aaa", "bbb", "ccc" }; object[] temp2 = new string[] { "aaa", "bbb", "ccc" }; object[] temp3 = new string[] { "aaa", "bbb", "ccc" }; // 配列データをバインド(型情報が必要) this._dam.SetParameter("P1", temp1, OracleDbType.Varchar2); this._dam.SetParameter("P2", temp2, OracleDbType.Varchar2); this._dam.SetParameter("P3", temp3, OracleDbType.Varchar2);
1つのXMLファイル中に200-300タグを超えてくると、オンライン処理でも性能が劣化が始まりますので、
不要なタグは記述しないようにお願いします(XMLファイル サイズについては、問題ないようです)。
上記のgist.github.comの性能測定の結果は、
fact(n) { if(n == 0) return 0; else return n * r + fact(n-1); }※ n 回再起して、r は1タグあたりのXMLDocument化のコスト。
<SELECT name="xxx"> <CASE value="A">・・・</CASE> <CASE value="B">・・・</CASE> <DEFAULT>・・・</DEFAULT> </SELECT>
- VAL Tag
- INSCOL Tag
- IF Tag
- Select-Case-Default Tag
- LIST Tag
- Sub-Where Tag
- DELCMA Tag
- Param Tag
具体的な性能は、動的パラメタライズド・クエリ分析ツールで測定可能です。
大量データ処理(バッチ更新処理)で
性能が出ません。
従って、大量データ処理の場合、バッチ処理方式を参照し、
などの技法を活用して、パフォーマンスを出す必要があります。
XML内部で使用不可能な文字列は、HTMLエンコーディングが必要になります。
これらの文字列が含まれる場合は、下記の現象が発生します。
として実行されるため、この現象は、不正なフォーマットのXMLを投げている事に起因します。
して下さい。
検索条件のIN句(副問合せ)を動的化する場合、
使用して下さい。
含むXMLタグを「再帰的」に検索し、
としています。
XMLタグの検索方法が再帰的なので、
<?xml version="1.0"?> <ROOT> SELECT * FROM Shippers <WHERE> WHERE <IF>ShipperID =@P1<ELSE>IS NULL</ELSE></IF> <IF>and ShipperID =@P1<ELSE>IS NULL</ELSE></IF> </WHERE> <PARAM> P1, Int32, 1<DIV/> </PARAM> </ROOT>
↓↓↓
SELECT * FROM Shippers WHERE ShipperID =@p1 and ShipperID =@p1
ようにします。
どのように渡すか?になりますが、
この部分はプロジェクト毎に検討ください。
SELECT * FROM AAA WHERE BBB = @P1
SELECT * FROM AAA WHERE BBB = CONVERT(varchar, @P1)