これは古い質問であることは承知していますが、最近、log4net を使用してパッケージ プロシージャに CLOB パラメータを渡す必要がありました。DbType を String に設定して Size を削除するなど、オンラインで見つけた提案を使用してそれを行うことができませんでした。
タイプ CLOB のパラメータを取る Oracle パッケージ プロシージャを使用しています。カスタム AdoNetAppenderParameter を使用すると、長い文字列 (270k 以上の文字) をプロシージャに渡し、DB (Oracle 9i) に格納できます。
まず、Oracle の Data Access Provider を使用する必要がありました (結局、Microsoft の System.Data.OracleClient は廃止されました)。プロジェクトは Oracle.DataAccess.dll を参照する必要があります。NuGet パッケージ マネージャーで「oracle.dataaccess」を検索して、NuGet パッケージを取得しました。
ライブラリには、 OracleDbType プロパティを持つDbParameterの実装 OracleParameter があります。プロパティのタイプは、 Clob値を持つ列挙型のOracleDbTypeです。
参照を追加した後、アペンダーの接続タイプを次のように変更しました。
<connectionType value="Oracle.DataAccess.Client.OracleConnection, Oracle.DataAccess, Version=2.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
次に、新しい OracleParameter を作成し、そのタイプを Clob に設定するカスタム AdoNetAppenderParameter を作成しました。
public class OracleAdoNetAppenderParameter : AdoNetAppenderParameter
{
public OracleDbType OracleDbType { get; set; }
public override void Prepare(System.Data.IDbCommand command)
{
if (!(command is OracleCommand))
{
string message = string.Format("The log4net parameter of type {0} can only be used with an appender connection of type {1}. The expected command type, {2}, cannot be supplied. Please check the parent appender's connectionType property.",
this.GetType(), typeof(OracleConnection), typeof(OracleCommand));
throw new System.ArgumentException(message, "command");
}
var parameter = command.CreateParameter() as OracleParameter;
parameter.ParameterName = base.ParameterName;
parameter.OracleDbType = this.OracleDbType;
command.Parameters.Add(parameter);
}
}
プロパティ OracleDbType を公開したので、構成を通じて指定できます。
最初はプロパティを公開せず、OracleClobAdoNetAppenderParameter クラスという名前を付け、Prepare メソッド内で OracleDbType プロパティを Clob に設定しました。
クラスを作成した後、次のようにパラメーターをアペンダーの構成に追加しました。
<parameter type="YourNamespace.OracleAdoNetAppenderParameter, YourAssembly">
<OracleDbType value="Clob" />
<parameterName value=":yourProcedureClobParam"/>
<layout type="..."></layout>
</parameter>
独自のレイアウトを使用できます。カスタムパラメータとしてlog4netのコンテキストを介して大きな文字列を渡しています。
私が使用している最終的な構成は次のとおりです。
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<connectionType value="Oracle.DataAccess.Client.OracleConnection, Oracle.DataAccess, Version=2.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
<connectionString value="data source=xxx;User ID=xxx;Password=xxx"/>
<commandText value="MY_PKG.LogMessage"/>
<commandType value="StoredProcedure" />
<!-- SERVICE_MESSAGE -->
<parameter type="MyNamespace.OracleAdoNetAppenderParameter, MyAssembly">
<OracleDbType value="Clob" />
<parameterName value=":service_message"/>
<layout type="log4net.Layout.RawPropertyLayout">
<key value="service_message"/>
</layout>
</parameter>
<!-- LOG_LEVEL -->
<parameter>
<parameterName value=":type"/>
<dbType value="String"/>
<size value="20"/>
<layout type="log4net.Layout.PatternLayout" value="%level"/>
</parameter>
<!-- LOG_DATE -->
<parameter>
<parameterName value=":timestamp"/>
<dbType value="DateTime"/>
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<!-- MESSAGE -->
<parameter>
<parameterName value=":message"/>
<dbType value="String"/>
<size value="1000"/>
<layout type="log4net.Layout.PatternLayout" value="%message"/>
</parameter>
<!-- EXCEPTION -->
<parameter>
<parameterName value=":error"/>
<dbType value="String"/>
<size value="4000"/>
<layout type="log4net.Layout.ExceptionLayout"/>
</parameter>
......
</appender>
それが役に立てば幸い。