FAQ - D層フレームワーク
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
「[[Open棟梁 wiki>https://opentouryo.osscons.jp]]」は、「...
-[[戻る>FAQ]]
--[[P層フレームワーク>FAQ - P層フレームワーク]]
--[[B層フレームワーク>FAQ - B層フレームワーク]]
--D層フレームワーク
--[[大規模案件導入>FAQ - 大規模案件導入]]
--[[その他>FAQ - その他]]
*目次 [#ceca0ef7]
#contents
*パラメタライズド・クエリ [#ha6bb666]
[[動的パラメタライズド・クエリの仕様]]
-Like検索は標準のパラメタライズド・クエリ、[[動的パラメタ...
-パラメタライズド・クエリのパラメタにnullを渡したい場合、...
**パラメタライズド・クエリのバインド変数への [#hf0a5243]
***バインド方法は? [#mbcbdc8e]
名前バインドにのみ対応しています。このため、どのデータプ...
-ODP.NETのバインドは名前バインド固定になります。
-OLEDB、ODBC、HiRDBのデータプロバイダは~
「?」パラメタの順番バインドにのみ対応しているためフレーム...
なお、制限事項として、コメント中に パラメタ名と同じ文字列...
***パラメタ属性指定方法は? [#hbfb130e]
-SetParameter()メソッドで型(、サイズ、方向)を指定可能で...
-後工程でのPG修正が難しい場合は、SQL定義ファイル中に[[型...
-[[自動生成Daoでもパラメタ属性指定が可能になりました。>自...
**ストアド プロシジャ、無名PL/SQLブロックの実行や、戻り値...
ストアド プロシジャでも[[動的パラメタライズド・クエリ]]機...
***ストアド プロシジャの実行方法 [#baebe4d6]
ストアド プロシージャの実行も可能である。
-ポイント
--CommandTypeにStoredProcedureを設定する。
--戻り値用のパラメタを指定する場合、
---Parameter.Directionプロパティに、
---ParameterDirection.ReturnValueを指定。
--アウトプット・パラメタを指定する場合、
---Parameter.Directionプロパティに、
---ParameterDirection.Outputを指定。
--実行には、this.ExecSelect_DR()メソッドを使用する。
--結果セットが複数ある場合
---ループなどを使用して複数の結果セットを取得できる。
---DataTable.Load()メソッドでは、結果セットが自動的に次に...
---DataTable.Load()メソッドを使用しない場合、~
DataReader.NextResult()メソッドを使用して、次に読む結果セ...
-サンプル~
ストアド プロシージャの実行については下記のコードを参考の...
/// <summary>「sp_help」ストアドプロシージャを実行する。...
/// <param name="objectName">「sp_help」ストアドプロシー...
/// <param name="ds">「sp_help」ストアドプロシージャが返...
/// <returns>「sp_help」ストアドプロシージャの戻り値(成...
public int sp_help(string objectName, out DataSet ds)
{
// ストアドプロシージャを指定する。
this.SetSqlByCommand("sp_help", CommandType.StoredProc...
// 引数パラメタを設定する。
this.SetParameter("objname", objectName);
// 戻り値パラメタを設定する。
this.SetParameter("ret", null, null, -1, ParameterDire...
// ストアドプロシージャを実行し、データリーダを戻す。
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.P...
}
***[[汎用Dao(CmnDao)>D層(Dao)の種類#f357a5ed]]経由での...
-Open棟梁の[[汎用Dao(CmnDao)>D層(Dao)の種類#f357a5ed]]...
https://gist.github.com/daisukenishino2/a97e2017a0c683d2c...
**デッドロック、ロックタイムアウト、「ユニークキーの重複...
B層[[ベースクラス2]]の例外処理をカスタマイズして、 リトラ...
**SetUserParameter()メソッドの利用ポリシーをどのように考...
-SetUserParameter()メソッドは、SQLインジェクションの可能...
-このため、SetUserParameter()メソッドの利用を制限せず、D...
SQLインジェクションの可能性があるSQLをチェック & Warning...
**[[D層自動生成ツール]]で楽観排他を、どのように実装するの...
-[[D層自動生成ツール]]でのDao生成時にタイムスタンプ列名を...
タイムスタンプ必須オプションONにして生成することで楽観排...
-[[自動生成Dao>D層(Dao)の種類#t389966a]]クラスを利用し...
更新系は[[自動生成Dao>D層(Dao)の種類#t389966a]]を必ず利...
**OracleのCLOBをODP.NET経由でどう扱うのか? [#i83e9e27]
-以下のADO.NETサンプルを参考に実装できると思います。
-[[自動生成Dao>D層(Dao)の種類#t389966a]]からだと上手く...
***サンプル [#a2aefe32]
-Insert(VB.NET)
Dim sr As New System.IO.StreamReader("C:\temp\input.txt"...
Dim ts as String
ts = sr.ReadToEnd()
sr.Close()
Dim fs As New System.IO.FileStream("C:\temp\input.gif",S...
Dim bs(fs.Length) As Byte
fs.Read(bs,0,fs.Length)
cmd.CommandText = "INSERT INTO TLOB(NO,TEXT,IMG) VALUES(...
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()
-Select(C#)
cmd.CommandText = "SELECT id, clob_column FROM clob_cont...
OracleDataReader reader = cmd.ExecuteReader();
reader.Read();
-Update(C#)
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();
***参考 [#tac45af6]
-.NETでラージ・オブジェクトを使用する~
http://www.oracle.com/technetwork/jp/articles/price-dotne...
-How To資料: ODP.NETによるLOB更新のための結果セットのロッ...
http://otndnld.oracle.co.jp/tech/windows/odpnet/howto/03_...
-ODP.NET 005 LOB INSERT - jnjnslabの備忘録~
http://jnjnslab.hatenablog.com/entry/2017/03/23/123810
*性能 [#v72fa9e1]
**コマンド タイムアウト値を設定するにはどうすれば良いか?...
共通のコマンド タイムアウト値をconfigファイルに設定できま...
**DataTableを利用している場合に処理時間が遅い [#k1ad92f5]
***概要 [#w7e4bfc8]
100,000件 selectの処理を調査したところ、~
単体でのSQL実行(SQL Server上でのselect文発行)のレスポン...
データ取得後のDataTableへのデータ設定で、8秒を使用してい...
***対策 [#a181d0f9]
Datatableは少々重いので、大量データには不向きかもしれませ...
DataTableではなくDataReaderを使用するAPIを使用すると良い...
-public abstract void ExecSelectFill_DT(DataTable dt);~
https://github.com/OpenTouryoProject/OpenTouryo/blob/deve...
-public abstract IDataReader ExecSelect_DR();~
https://github.com/OpenTouryoProject/OpenTouryo/blob/deve...
自動生成Daoで使用する場合は、テンプレートを修正すればいけ...
https://github.com/OpenTouryoProject/OpenTouryo/blob/deve...
**ODP.NET、HiRDBの配列バインドをサポートしているか? [#db...
-ODP.NET、HiRDBの配列バインドをサポートしています。
-また、配列バインドをサポートしていないデータプロバイダで...
大量データ処理実装のために、[[バッチクエリ作成支援機能]]...
***ポイント [#s72139d0]
ODP.NET配列バインドの場合、
-パラメタ
--ArrayBindCountの指定が必要。
--OracleDbTypeの型指定が必要。
-Dam取得方法
--B層でDamを取得する場合は、((DamOraOdp)this.GetDam())
--「[[自作Daoクラス>D層(Dao)の種類#p684509d]]」でDamを...
--「[[Dao集約クラス>D層(Dao)の種類#ra46728e]]」でDamを...
-[[動的パラメタライズド・クエリ分析ツール]]も、「配列バイ...
***サンプル [#g6a81f58]
以下、ODP.NETのサンプル([[自作Daoクラス>D層(Dao)の種類...
// SQLを設定
this.SetSqlByCommand("INSERT INTO XXX(AAA, BBB, CCC) VAL...
// ODP.NETの配列バインドの場合は、ArrayBindCountを指定
((DamOraOdp)this._dam).DamOracleCommand.ArrayBindCount =...
// 配列データを作成
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.Varchar...
this._dam.SetParameter("P2", temp2, OracleDbType.Varchar...
this._dam.SetParameter("P3", temp3, OracleDbType.Varchar...
**SQLで暗黙の型変換が発生し、検索処理性能が大幅に劣化する...
***対策 [#y72939b8]
-SetParameter()メソッドで型、サイズ、方向を指定可能です。
-後工程でのPG修正が難しい場合は、SQL定義ファイル中に[[型...
***[[参考>データアクセス#e9d7a80e]] [#b07964e5]
**[[動的パラメタライズド・クエリ]]を記述するXMLファイルの...
***概要 [#tdca75f6]
1つのXMLファイル中に200-300タグを超えてくると、オンライ...
不要なタグは記述しないようにお願いします(XMLファイル サ...
-Open棟梁:動的パラメタライズド・クエリの性能測定に使用し...
https://gist.github.com/daisukenishino2/c2da7b9fadf79c2ba...
***詳細 [#m2b746e7]
上記のgist.github.comの性能測定の結果は、
-すべてのタグをフラットに並べたケースで、~
タグ数が n の場合、計算量は以下のように定義できます。
fact(n)
{
if(n == 0) return 0;
else return n * r + fact(n-1);
}
※ n 回再起して、r は1タグあたりのXMLDocument化のコスト。
-タグがフラットに並んでいないケースでは、~
以下のように計算量が変わってきます。
--以下のようなSELECTタグは、
---読込時、4タグのオーバーヘッドはありますが、
---再帰処理回数への影響は、+1回になります。
<SELECT name="xxx">
<CASE value="A">・・・</CASE>
<CASE value="B">・・・</CASE>
<DEFAULT>・・・</DEFAULT>
</SELECT>
--ネスト可能なタグの処理順は後半になるので影響はありませ...
https://github.com/OpenTouryoProject/OpenTouryo/blob/deve...
>
+VAL Tag
+INSCOL Tag
+IF Tag
+Select-Case-Default Tag
+LIST Tag
+Sub-Where Tag
+DELCMA Tag
+Param Tag
-なお、[[動的パラメタライズド・クエリ分析ツール]]を使用し...
テストのために記述するPARAMタグ、DIVタグなどXMLドキュメン...
更新処理を伴わないタグについては、再起処理数に影響を与え...
***測定 [#fa6e9f15]
具体的な性能は、[[動的パラメタライズド・クエリ分析ツール]...
-Demo: dynamic parametrized query analysis tool of Open棟...
https://www.youtube.com/watch?v=6_8baBTVcRM
***解決方法 [#h87ce66e]
-[[自作Daoで解決>バッチ処理方式#r8d98838]]
-[[自動生成Daoで解決>バッチ処理方式#u9c20643]]
**大量データ処理(バッチ更新処理)をサポートしているか? ...
***概要 [#s92d899d]
大量データ処理(バッチ更新処理)で
-[[オーバーヘッドのある動的SQL>#o6536f12]]を使用したり、
-1件1件のクエリを発行して多くのラウンドトリップを発生さ...
性能が出ません。
***対策 [#la1c4723]
従って、大量データ処理の場合、[[バッチ処理方式]]を参照し、
-[[配列バインド(ODP.NET、HiRDBでサポート)>バッチ処理方...
-[[バッチクエリ作成支援機能>バッチ処理方式#ze851f70]]
-[[動的パラメタライズド・クエリの連続実行方法>バッチ処理...
などの技法を活用して、パフォーマンスを出す必要があります。
*エラー [#g7fbf41d]
**[[動的パラメタライズド・クエリ]]で、[<]、[>]などの文字...
XML内部で使用不可能な文字列は、[[HTMLエンコーディング>htt...
これらの文字列が含まれる場合は、[[下記の現象>#g5a1aa8a]]...
**[[動的パラメタライズド・クエリ]]でXMLが編集されずに、そ...
-DB部品の最も初めのチェック処理にXmlDocument.Load()メソッ...
--XMLフォーマットとして正しいものは[[動的パラメタライズド...
--不正であるものは[[静的パラメタライズド・クエリ]]
>として実行されるため、この現象は、不正なフォーマットのXM...
-XMLフォーマットの不正を確認するためには、
--[[動的パラメタライズド・クエリ分析ツール]]を使用するか、
--デバッグ時に、DB部品クラスのIsDPQプロパティ(動的SQLか...
>して下さい。
**[[自動生成Dao>D層(Dao)の種類#t389966a]]の Update処理...
-[[D層自動生成ツール]]は、Update時に使用するパラメタ識別...
1文字以上のプレフィックス・サフィックスを追加する必要が...
-この際、パラメタ識別子が30文字を越えてしまい、エラーが発...
-プレフィックス・サフィックスは、[[D層自動生成ツール]]の...
-この再設定と、再生成が面倒な場合は、文字列一括置換ツール...
置換するなどして下さい(DaoとUpdate処理のSQL定義(XML)が...
**検索条件のIN句(副問合せ)を動的化したいがエラーとなる...
検索条件のIN句(副問合せ)を動的化する場合、
[[動的パラメタライズド・クエリ]]の
-IFタグ ではなく、
-タグのネストが可能なSUBタグを
使用して下さい。
*Daoの使い分け [#m93cb89e]
**更新系処理 [#ibb5dec2]
[[自動生成Dao>D層(Dao)の種類#t389966a]]
**単一テーブルからのSELECT [#v7b6eb62]
[[自動生成Dao>D層(Dao)の種類#t389966a]]
**複数テーブルなど複雑なSELECT [#w6260481]
[[汎用Dao(CmnDao)>D層(Dao)の種類#f357a5ed]]
*制限事項 [#s54b0aae]
**[[動的パラメタライズド・クエリ]]のパラメタ名 [#o212ae41]
-[[動的パラメタライズド・クエリ]]のパラメタで、~
XMLタグの編集処理に使用されるパラメタ(タグ内パラメタ)の~
パラメタ名は、(同じ値を使用するパラメタであっても、)~
別々に(1つのXMLタグ毎、ユニークに)定義する必要がありま...
-この理由は、以下のような[[アルゴリズム>#vdacfa6a]]に起因...
***アルゴリズム [#vdacfa6a]
-アルゴリズムとしては、
--テキスト内パラメタや
--タグ内パラメタを
>含むXMLタグを「再帰的」に検索し、
-パラメタ設定されていれば、
--テキスト内パラメタのあるXMLタグを有効化
--タグ内パラメタのあるXMLタグを有効化(その際、パラメタは...
>としています。
***結論 [#s9de7ded]
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
*サポート [#jeee821d]
**Like句を使用した曖昧検索をサポートしているか? [#y89659...
-サポートしています。
-パラメタライズド・クエリ自体がLike句を使用した曖昧検索を...
文字列連結やSetUserParameter()メソッドを使用する必要はあ...
**LINQ や Entity Frameworkをサポートしているか? [#d17aa7...
-利用制限はしていません(機能提供は無し)。
-D層フレームワーク(静/[[動的パラメタライズド・クエリ]]機...
**任意のDLL(Assembly)からの埋込SQLのロードをサポートし...
-[[ベースクラス2]]のSetSqlByFile2メソッドを用いてExecutin...
任意のDLL(Assembly)から埋込リソースをロードを行う場合は...
-カスタマイズ方法は、SetSqlByFile2メソッドで、
--EmbeddedResourceLoader.LoadAsStringメソッドを使用して ...
--this.SetSqlByCommandメソッドでSQLを設定する
>ようにします。
-問題は、EmbeddedResourceLoader.LoadAsStringメソッドの引...
--assemblyStringと、
--loadfileNameに組み込む名前空間情報を
>どのように渡すか?になりますが、~
この部分はプロジェクト毎に検討ください。
*参考 [#c03f88d3]
**型キャスト [#ffce50b2]
-暗黙の型変換の発生例
SELECT * FROM AAA WHERE BBB = @P1
-暗黙の型変換の抑止
SELECT * FROM AAA WHERE BBB = CONVERT(varchar, @P1)
**doc [#z81df200]
-.NET用アプリケーション フレームワーク ”棟梁” 利用ガイド...
https://github.com/OpenTouryoProject/OpenTouryoDocuments/...
--4章:「D層に関するトピック」も参考にして下さい。
--7章:「FAQ」> 7.3節:「D層フレームワーク」も参考にして下...
終了行:
「[[Open棟梁 wiki>https://opentouryo.osscons.jp]]」は、「...
-[[戻る>FAQ]]
--[[P層フレームワーク>FAQ - P層フレームワーク]]
--[[B層フレームワーク>FAQ - B層フレームワーク]]
--D層フレームワーク
--[[大規模案件導入>FAQ - 大規模案件導入]]
--[[その他>FAQ - その他]]
*目次 [#ceca0ef7]
#contents
*パラメタライズド・クエリ [#ha6bb666]
[[動的パラメタライズド・クエリの仕様]]
-Like検索は標準のパラメタライズド・クエリ、[[動的パラメタ...
-パラメタライズド・クエリのパラメタにnullを渡したい場合、...
**パラメタライズド・クエリのバインド変数への [#hf0a5243]
***バインド方法は? [#mbcbdc8e]
名前バインドにのみ対応しています。このため、どのデータプ...
-ODP.NETのバインドは名前バインド固定になります。
-OLEDB、ODBC、HiRDBのデータプロバイダは~
「?」パラメタの順番バインドにのみ対応しているためフレーム...
なお、制限事項として、コメント中に パラメタ名と同じ文字列...
***パラメタ属性指定方法は? [#hbfb130e]
-SetParameter()メソッドで型(、サイズ、方向)を指定可能で...
-後工程でのPG修正が難しい場合は、SQL定義ファイル中に[[型...
-[[自動生成Daoでもパラメタ属性指定が可能になりました。>自...
**ストアド プロシジャ、無名PL/SQLブロックの実行や、戻り値...
ストアド プロシジャでも[[動的パラメタライズド・クエリ]]機...
***ストアド プロシジャの実行方法 [#baebe4d6]
ストアド プロシージャの実行も可能である。
-ポイント
--CommandTypeにStoredProcedureを設定する。
--戻り値用のパラメタを指定する場合、
---Parameter.Directionプロパティに、
---ParameterDirection.ReturnValueを指定。
--アウトプット・パラメタを指定する場合、
---Parameter.Directionプロパティに、
---ParameterDirection.Outputを指定。
--実行には、this.ExecSelect_DR()メソッドを使用する。
--結果セットが複数ある場合
---ループなどを使用して複数の結果セットを取得できる。
---DataTable.Load()メソッドでは、結果セットが自動的に次に...
---DataTable.Load()メソッドを使用しない場合、~
DataReader.NextResult()メソッドを使用して、次に読む結果セ...
-サンプル~
ストアド プロシージャの実行については下記のコードを参考の...
/// <summary>「sp_help」ストアドプロシージャを実行する。...
/// <param name="objectName">「sp_help」ストアドプロシー...
/// <param name="ds">「sp_help」ストアドプロシージャが返...
/// <returns>「sp_help」ストアドプロシージャの戻り値(成...
public int sp_help(string objectName, out DataSet ds)
{
// ストアドプロシージャを指定する。
this.SetSqlByCommand("sp_help", CommandType.StoredProc...
// 引数パラメタを設定する。
this.SetParameter("objname", objectName);
// 戻り値パラメタを設定する。
this.SetParameter("ret", null, null, -1, ParameterDire...
// ストアドプロシージャを実行し、データリーダを戻す。
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.P...
}
***[[汎用Dao(CmnDao)>D層(Dao)の種類#f357a5ed]]経由での...
-Open棟梁の[[汎用Dao(CmnDao)>D層(Dao)の種類#f357a5ed]]...
https://gist.github.com/daisukenishino2/a97e2017a0c683d2c...
**デッドロック、ロックタイムアウト、「ユニークキーの重複...
B層[[ベースクラス2]]の例外処理をカスタマイズして、 リトラ...
**SetUserParameter()メソッドの利用ポリシーをどのように考...
-SetUserParameter()メソッドは、SQLインジェクションの可能...
-このため、SetUserParameter()メソッドの利用を制限せず、D...
SQLインジェクションの可能性があるSQLをチェック & Warning...
**[[D層自動生成ツール]]で楽観排他を、どのように実装するの...
-[[D層自動生成ツール]]でのDao生成時にタイムスタンプ列名を...
タイムスタンプ必須オプションONにして生成することで楽観排...
-[[自動生成Dao>D層(Dao)の種類#t389966a]]クラスを利用し...
更新系は[[自動生成Dao>D層(Dao)の種類#t389966a]]を必ず利...
**OracleのCLOBをODP.NET経由でどう扱うのか? [#i83e9e27]
-以下のADO.NETサンプルを参考に実装できると思います。
-[[自動生成Dao>D層(Dao)の種類#t389966a]]からだと上手く...
***サンプル [#a2aefe32]
-Insert(VB.NET)
Dim sr As New System.IO.StreamReader("C:\temp\input.txt"...
Dim ts as String
ts = sr.ReadToEnd()
sr.Close()
Dim fs As New System.IO.FileStream("C:\temp\input.gif",S...
Dim bs(fs.Length) As Byte
fs.Read(bs,0,fs.Length)
cmd.CommandText = "INSERT INTO TLOB(NO,TEXT,IMG) VALUES(...
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()
-Select(C#)
cmd.CommandText = "SELECT id, clob_column FROM clob_cont...
OracleDataReader reader = cmd.ExecuteReader();
reader.Read();
-Update(C#)
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();
***参考 [#tac45af6]
-.NETでラージ・オブジェクトを使用する~
http://www.oracle.com/technetwork/jp/articles/price-dotne...
-How To資料: ODP.NETによるLOB更新のための結果セットのロッ...
http://otndnld.oracle.co.jp/tech/windows/odpnet/howto/03_...
-ODP.NET 005 LOB INSERT - jnjnslabの備忘録~
http://jnjnslab.hatenablog.com/entry/2017/03/23/123810
*性能 [#v72fa9e1]
**コマンド タイムアウト値を設定するにはどうすれば良いか?...
共通のコマンド タイムアウト値をconfigファイルに設定できま...
**DataTableを利用している場合に処理時間が遅い [#k1ad92f5]
***概要 [#w7e4bfc8]
100,000件 selectの処理を調査したところ、~
単体でのSQL実行(SQL Server上でのselect文発行)のレスポン...
データ取得後のDataTableへのデータ設定で、8秒を使用してい...
***対策 [#a181d0f9]
Datatableは少々重いので、大量データには不向きかもしれませ...
DataTableではなくDataReaderを使用するAPIを使用すると良い...
-public abstract void ExecSelectFill_DT(DataTable dt);~
https://github.com/OpenTouryoProject/OpenTouryo/blob/deve...
-public abstract IDataReader ExecSelect_DR();~
https://github.com/OpenTouryoProject/OpenTouryo/blob/deve...
自動生成Daoで使用する場合は、テンプレートを修正すればいけ...
https://github.com/OpenTouryoProject/OpenTouryo/blob/deve...
**ODP.NET、HiRDBの配列バインドをサポートしているか? [#db...
-ODP.NET、HiRDBの配列バインドをサポートしています。
-また、配列バインドをサポートしていないデータプロバイダで...
大量データ処理実装のために、[[バッチクエリ作成支援機能]]...
***ポイント [#s72139d0]
ODP.NET配列バインドの場合、
-パラメタ
--ArrayBindCountの指定が必要。
--OracleDbTypeの型指定が必要。
-Dam取得方法
--B層でDamを取得する場合は、((DamOraOdp)this.GetDam())
--「[[自作Daoクラス>D層(Dao)の種類#p684509d]]」でDamを...
--「[[Dao集約クラス>D層(Dao)の種類#ra46728e]]」でDamを...
-[[動的パラメタライズド・クエリ分析ツール]]も、「配列バイ...
***サンプル [#g6a81f58]
以下、ODP.NETのサンプル([[自作Daoクラス>D層(Dao)の種類...
// SQLを設定
this.SetSqlByCommand("INSERT INTO XXX(AAA, BBB, CCC) VAL...
// ODP.NETの配列バインドの場合は、ArrayBindCountを指定
((DamOraOdp)this._dam).DamOracleCommand.ArrayBindCount =...
// 配列データを作成
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.Varchar...
this._dam.SetParameter("P2", temp2, OracleDbType.Varchar...
this._dam.SetParameter("P3", temp3, OracleDbType.Varchar...
**SQLで暗黙の型変換が発生し、検索処理性能が大幅に劣化する...
***対策 [#y72939b8]
-SetParameter()メソッドで型、サイズ、方向を指定可能です。
-後工程でのPG修正が難しい場合は、SQL定義ファイル中に[[型...
***[[参考>データアクセス#e9d7a80e]] [#b07964e5]
**[[動的パラメタライズド・クエリ]]を記述するXMLファイルの...
***概要 [#tdca75f6]
1つのXMLファイル中に200-300タグを超えてくると、オンライ...
不要なタグは記述しないようにお願いします(XMLファイル サ...
-Open棟梁:動的パラメタライズド・クエリの性能測定に使用し...
https://gist.github.com/daisukenishino2/c2da7b9fadf79c2ba...
***詳細 [#m2b746e7]
上記のgist.github.comの性能測定の結果は、
-すべてのタグをフラットに並べたケースで、~
タグ数が n の場合、計算量は以下のように定義できます。
fact(n)
{
if(n == 0) return 0;
else return n * r + fact(n-1);
}
※ n 回再起して、r は1タグあたりのXMLDocument化のコスト。
-タグがフラットに並んでいないケースでは、~
以下のように計算量が変わってきます。
--以下のようなSELECTタグは、
---読込時、4タグのオーバーヘッドはありますが、
---再帰処理回数への影響は、+1回になります。
<SELECT name="xxx">
<CASE value="A">・・・</CASE>
<CASE value="B">・・・</CASE>
<DEFAULT>・・・</DEFAULT>
</SELECT>
--ネスト可能なタグの処理順は後半になるので影響はありませ...
https://github.com/OpenTouryoProject/OpenTouryo/blob/deve...
>
+VAL Tag
+INSCOL Tag
+IF Tag
+Select-Case-Default Tag
+LIST Tag
+Sub-Where Tag
+DELCMA Tag
+Param Tag
-なお、[[動的パラメタライズド・クエリ分析ツール]]を使用し...
テストのために記述するPARAMタグ、DIVタグなどXMLドキュメン...
更新処理を伴わないタグについては、再起処理数に影響を与え...
***測定 [#fa6e9f15]
具体的な性能は、[[動的パラメタライズド・クエリ分析ツール]...
-Demo: dynamic parametrized query analysis tool of Open棟...
https://www.youtube.com/watch?v=6_8baBTVcRM
***解決方法 [#h87ce66e]
-[[自作Daoで解決>バッチ処理方式#r8d98838]]
-[[自動生成Daoで解決>バッチ処理方式#u9c20643]]
**大量データ処理(バッチ更新処理)をサポートしているか? ...
***概要 [#s92d899d]
大量データ処理(バッチ更新処理)で
-[[オーバーヘッドのある動的SQL>#o6536f12]]を使用したり、
-1件1件のクエリを発行して多くのラウンドトリップを発生さ...
性能が出ません。
***対策 [#la1c4723]
従って、大量データ処理の場合、[[バッチ処理方式]]を参照し、
-[[配列バインド(ODP.NET、HiRDBでサポート)>バッチ処理方...
-[[バッチクエリ作成支援機能>バッチ処理方式#ze851f70]]
-[[動的パラメタライズド・クエリの連続実行方法>バッチ処理...
などの技法を活用して、パフォーマンスを出す必要があります。
*エラー [#g7fbf41d]
**[[動的パラメタライズド・クエリ]]で、[<]、[>]などの文字...
XML内部で使用不可能な文字列は、[[HTMLエンコーディング>htt...
これらの文字列が含まれる場合は、[[下記の現象>#g5a1aa8a]]...
**[[動的パラメタライズド・クエリ]]でXMLが編集されずに、そ...
-DB部品の最も初めのチェック処理にXmlDocument.Load()メソッ...
--XMLフォーマットとして正しいものは[[動的パラメタライズド...
--不正であるものは[[静的パラメタライズド・クエリ]]
>として実行されるため、この現象は、不正なフォーマットのXM...
-XMLフォーマットの不正を確認するためには、
--[[動的パラメタライズド・クエリ分析ツール]]を使用するか、
--デバッグ時に、DB部品クラスのIsDPQプロパティ(動的SQLか...
>して下さい。
**[[自動生成Dao>D層(Dao)の種類#t389966a]]の Update処理...
-[[D層自動生成ツール]]は、Update時に使用するパラメタ識別...
1文字以上のプレフィックス・サフィックスを追加する必要が...
-この際、パラメタ識別子が30文字を越えてしまい、エラーが発...
-プレフィックス・サフィックスは、[[D層自動生成ツール]]の...
-この再設定と、再生成が面倒な場合は、文字列一括置換ツール...
置換するなどして下さい(DaoとUpdate処理のSQL定義(XML)が...
**検索条件のIN句(副問合せ)を動的化したいがエラーとなる...
検索条件のIN句(副問合せ)を動的化する場合、
[[動的パラメタライズド・クエリ]]の
-IFタグ ではなく、
-タグのネストが可能なSUBタグを
使用して下さい。
*Daoの使い分け [#m93cb89e]
**更新系処理 [#ibb5dec2]
[[自動生成Dao>D層(Dao)の種類#t389966a]]
**単一テーブルからのSELECT [#v7b6eb62]
[[自動生成Dao>D層(Dao)の種類#t389966a]]
**複数テーブルなど複雑なSELECT [#w6260481]
[[汎用Dao(CmnDao)>D層(Dao)の種類#f357a5ed]]
*制限事項 [#s54b0aae]
**[[動的パラメタライズド・クエリ]]のパラメタ名 [#o212ae41]
-[[動的パラメタライズド・クエリ]]のパラメタで、~
XMLタグの編集処理に使用されるパラメタ(タグ内パラメタ)の~
パラメタ名は、(同じ値を使用するパラメタであっても、)~
別々に(1つのXMLタグ毎、ユニークに)定義する必要がありま...
-この理由は、以下のような[[アルゴリズム>#vdacfa6a]]に起因...
***アルゴリズム [#vdacfa6a]
-アルゴリズムとしては、
--テキスト内パラメタや
--タグ内パラメタを
>含むXMLタグを「再帰的」に検索し、
-パラメタ設定されていれば、
--テキスト内パラメタのあるXMLタグを有効化
--タグ内パラメタのあるXMLタグを有効化(その際、パラメタは...
>としています。
***結論 [#s9de7ded]
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
*サポート [#jeee821d]
**Like句を使用した曖昧検索をサポートしているか? [#y89659...
-サポートしています。
-パラメタライズド・クエリ自体がLike句を使用した曖昧検索を...
文字列連結やSetUserParameter()メソッドを使用する必要はあ...
**LINQ や Entity Frameworkをサポートしているか? [#d17aa7...
-利用制限はしていません(機能提供は無し)。
-D層フレームワーク(静/[[動的パラメタライズド・クエリ]]機...
**任意のDLL(Assembly)からの埋込SQLのロードをサポートし...
-[[ベースクラス2]]のSetSqlByFile2メソッドを用いてExecutin...
任意のDLL(Assembly)から埋込リソースをロードを行う場合は...
-カスタマイズ方法は、SetSqlByFile2メソッドで、
--EmbeddedResourceLoader.LoadAsStringメソッドを使用して ...
--this.SetSqlByCommandメソッドでSQLを設定する
>ようにします。
-問題は、EmbeddedResourceLoader.LoadAsStringメソッドの引...
--assemblyStringと、
--loadfileNameに組み込む名前空間情報を
>どのように渡すか?になりますが、~
この部分はプロジェクト毎に検討ください。
*参考 [#c03f88d3]
**型キャスト [#ffce50b2]
-暗黙の型変換の発生例
SELECT * FROM AAA WHERE BBB = @P1
-暗黙の型変換の抑止
SELECT * FROM AAA WHERE BBB = CONVERT(varchar, @P1)
**doc [#z81df200]
-.NET用アプリケーション フレームワーク ”棟梁” 利用ガイド...
https://github.com/OpenTouryoProject/OpenTouryoDocuments/...
--4章:「D層に関するトピック」も参考にして下さい。
--7章:「FAQ」> 7.3節:「D層フレームワーク」も参考にして下...
ページ名: