Oracle Data Provider for .NET(ODP.NET)ドライバの問題
症状
OutSystems開発者がConfiguration ToolやService Studioを使用しているとき、いくつかの問題が発生する場合があります。Platform Serverを実行しているPCのGACのODP.NETドライバのバージョンがOutSystemsプラットフォームで使用されているバージョン(4.121.2.20150926)と異なる場合、エラーが発生する可能性があります。
エラーメッセージの例1: アプリケーション実行時のエラー
Unsupported column datatype
at OracleInternal.TTC.TTCExecuteSql.ReceiveExecuteResponse(Accessor[]& defineAccessors, Accessor[] bindAccessors, Boolean bHasReturningParams, SQLMetaData& sqlMetaData, SqlStatementType statementType, Int64 noOfRowsFetchedLastTime, Int32 noOfRowsToFetch, Int32& noOfRowsFetched, Int64& queryId, Int32 longFetchSize, Int64 initialLOBFetchSize, Int64[] scnFromExecution, Boolean& bAllPureInputBinds, DataUnmarshaller& dataUnmarshaller, MarshalBindParameterValueHelper& marshalBindParamsHelper, Int64[]& rowsAffectedByArrayBind, Boolean bDefineDone, Boolean& bMoreThanOneRowAffectedByDmlWithRetClause, Boolean bLOBArrayFetchRequired)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteReader(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, OracleDataReaderImpl& rdrImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[] scnForExecution, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, Int64& internalInitialLOBFS, OracleException& exceptionForArrayBindDML, Boolean isDescribeOnly, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteDbDataReader(CommandBehavior behavior)
at OutSystems.HubEdition.DatabaseProvider.Oracle.ExecutionService.ExecutionService.ExecuteReader(IDbCommand cmd)
at OutSystems.Internal.Db.ManagedCommand.ExecuteReader(String description, Boolean isApplication, Boolean transformParameters, Boolean skipLog)
at OutSystems.Internal.Db.DatabaseAccessProvider`1.ExecuteQuery[T](Command cmd, GenericRecordList`1 rl, String description, Boolean transformParameters, Boolean skipLog)
at OutSystems.Internal.Db.DatabaseAccessProvider`1.ExecuteQuery[T](Command cmd, GenericRecordList`1 rl, String description)
at ssXmlTypeApp.Flows.FlowMainFlow.ScrnHomeScreen.FuncssPreparation.datasetGetXmltypes(HeContext heContext, Int32 maxRecords, IterationMultiplicity multiplicity, Int64& outParamCount)
at ssXmlTypeApp.Flows.FlowMainFlow.ScrnHomeScreen.Preparation(HeContext heContext)
at ssXmlTypeApp.Flows.FlowMainFlow.ScrnHomeScreen.Page_Load(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
エラーメッセージの例2: Configuration Tool使用中のエラー
Error: Attempt by method 'OutSystems.HubEdition.DatabaseProvider.Oracle.ExecutionService.ExecutionService.TransformDatabaseToRuntimeValue(System.Object)' to access type 'Oracle.ManagedDataAccess.Types.OracleXmlType' failed.
at OutSystems.HubEdition.DatabaseProvider.Oracle.ExecutionService.ExecutionService.TransformDatabaseToRuntimeValue(Object value)in c:\Go\GoAgent2\pipelines\NRDevelopment\b10_0_0\HubServer\DatabaseProviders\OracleDatabaseProvider\ExecutionService\ExecutionService.cs:line 354
エラーメッセージの例3: Service Studioの高度なクエリ
「Database returned the following error:
Error in advanced query SQL1: Unsupported column datatype.」
図1 - 高度なクエリのエラー
原因
OutSystems 10では、(他にも軽微な変更がありますが、特に)XMLタイプのサポートが追加された新しいバージョンのODP.NETドライバを使用しています。このアップグレードは軽微な改定であるため、本来は問題は発生しません。
しかし残念ながら、バージョンメタデータが2つのアセンブリ(v4.121.2.0)間で変更されず、CLRアセンブリの解決プロセスでこれらを区別することができません。アセンブリの公開APIは変更されているため、いくつかの問題が発生する可能性があります。
図2と3は、これら2つのドライバのアセンブリのメタデータを示しています。
図2 - 以前のODP.NETドライバのメタデータ
図3 - 新しいODP.NETドライバのメタデータ
解決策
この問題が発生した場合、以下の手順を実行します。
- GAC内のOracle.ManagedDataAccess.dllを使用するアプリケーションがあるかどうかを確認します(この作業は容易ではありません。fuslogvwまたはプロセスエクスプローラを使用してみることができますが、これらによって表示されるのは過去/現在メモリ内に読み込まれたアセンブリのみです)。
- GAC内のDLLを使用するアプリケーションがある場合、DLLをGACからそれらのアプリケーションのAPPBaseディレクトリにコピーします。
- GACからDLLを削除します。これを行うには、以下に示すOracle OraProvCfg.exe(このアプリケーションはOracleのWebサイトでダウンロードすることができ、Oracle Data Access Componentsに含まれています)コマンドを使用します(管理者としてコマンドプロンプトを開きます)。
OraProvCfg.exe /action:ungac /providerpath:"Oracle.ManagedDataAccess"
図4 - GACからのOracle.ManagedDataAccess.dllの削除
または、GAC内のDLLをOutSystemsプラットフォームで使用されるもの(これもインストールに含まれています)に更新することもできます。
OraProvCfg.exe /action:gac /providerpath:"Oracle.ManagedDataAccess.dll"
図5 - GACのOracle.ManagedDataAccess.dllの更新/追加