「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句(副問合せ)を動的化する場合、
使用して下さい。
自動生成Dao
自動生成Dao
共通Dao(CmnDao)
含む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)