2012-04-19 20 views
1

OracleType 10gデータベースには、XMLTYPE値を返す関数が1つあります。コマンドオブジェクトのParameterDirection.ReturnValueを使用して関数から返された値を取得しようとしています。NHibernate Oracle XMLTypeの問題

が、我々は

System.Data.OracleClient.OracleException(0x80131938)としてエラーを取得していますORA-06550:行1、列27: PLS-00382:式が間違った型 ORA-06550は次のとおりです。行1、列7: PL/SQL:ステートメントが無視される

これを解決するには?

答えて

0

私はこれに取り組んで以来、私は問題を検証するための作業プロジェクトがありませんでしたが、私はこれがあなたの問題を解決すると信じています。

これをどのように解決したかは、nHibernateプロジェクトのカスタムビルドを行うことでした。 OracleDataClientDriver.csファイルを次のように編集しました。このファイルの現在のバージョンをダウンロードしたばかりで、私が修正してから2年間で少し変化していることに注意してください。 nHibernateリポジトリから現在のバージョンのファイルを取得し、貼り付けようとしているコードでファイルを変更すると、変更が表示されます。私の変更は行番号にあります(私の編集者によると)26、45、82-85。

修正のテーマは、nHibernateマッピング・ファイル・タイプからOracle Data Type for XMLへのマッピングを追加する必要があったことです。 Oracleドライバはこのタイプを処理しますが、nHibernateでそれを使用するロジックがありませんでした。以下はこれに対する修正です。

スタート貼り付け-----

using System.Data; 
using System.Reflection; 
using NHibernate.AdoNet; 
using NHibernate.Engine.Query; 
using NHibernate.SqlTypes; 
using NHibernate.Util; 

namespace NHibernate.Driver 
{ 
    /// <summary> 
    /// A NHibernate Driver for using the Oracle.DataAccess DataProvider 
    /// </summary> 
    /// <remarks> 
    /// Code was contributed by <a href="http://sourceforge.net/users/jemcalgary/">James Mills</a> 
    /// on the NHibernate forums in this 
    /// <a href="http://sourceforge.net/forum/message.php?msg_id=2952662">post</a>. 
    /// </remarks> 
    public class OracleDataClientDriver : ReflectionBasedDriver, IEmbeddedBatcherFactoryProvider 
    { 
     private const string driverAssemblyName = "Oracle.DataAccess"; 
     private const string connectionTypeName = "Oracle.DataAccess.Client.OracleConnection"; 
     private const string commandTypeName = "Oracle.DataAccess.Client.OracleCommand"; 
     private static readonly SqlType GuidSqlType = new SqlType(DbType.Binary, 16); 
     private readonly PropertyInfo oracleDbType; 
     private readonly object oracleDbTypeRefCursor; 
     private readonly object oracleDbTypeXmlType; 

     /// <summary> 
     /// Initializes a new instance of <see cref="OracleDataClientDriver"/>. 
     /// </summary> 
     /// <exception cref="HibernateException"> 
     /// Thrown when the <c>Oracle.DataAccess</c> assembly can not be loaded. 
     /// </exception> 
     public OracleDataClientDriver() 
      : base(
      driverAssemblyName, 
      connectionTypeName, 
      commandTypeName) 
     { 
      System.Type parameterType = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleParameter", driverAssemblyName, false); 
      oracleDbType = parameterType.GetProperty("OracleDbType"); 

      System.Type oracleDbTypeEnum = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleDbType", driverAssemblyName, false); 
      oracleDbTypeRefCursor = System.Enum.Parse(oracleDbTypeEnum, "RefCursor"); 
      oracleDbTypeXmlType = System.Enum.Parse(oracleDbTypeEnum, "XmlType"); 
     } 

     /// <summary></summary> 
     public override bool UseNamedPrefixInSql 
     { 
      get { return true; } 
     } 

     /// <summary></summary> 
     public override bool UseNamedPrefixInParameter 
     { 
      get { return true; } 
     } 

     /// <summary></summary> 
     public override string NamedPrefix 
     { 
      get { return ":"; } 
     } 

     /// <remarks> 
     /// This adds logic to ensure that a DbType.Boolean parameter is not created since 
     /// ODP.NET doesn't support it. 
     /// </remarks> 
     protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType) 
     { 
      // if the parameter coming in contains a boolean then we need to convert it 
      // to another type since ODP.NET doesn't support DbType.Boolean 
      switch (sqlType.DbType) 
      { 
       case DbType.Boolean: 
        base.InitializeParameter(dbParam, name, SqlTypeFactory.Int16); 
        break; 
       case DbType.Guid: 
        base.InitializeParameter(dbParam, name, GuidSqlType); 
        break; 
       case DbType.Xml: 
        dbParam.ParameterName = base.FormatNameForParameter(name); 
        oracleDbType.SetValue(dbParam, oracleDbTypeXmlType, null); 
        break; 
       default: 
        base.InitializeParameter(dbParam, name, sqlType); 
        break; 
      } 
     } 

     protected override void OnBeforePrepare(IDbCommand command) 
     { 
      base.OnBeforePrepare(command); 

      CallableParser.Detail detail = CallableParser.Parse(command.CommandText); 

      if (!detail.IsCallable) 
       return; 

      command.CommandType = CommandType.StoredProcedure; 
      command.CommandText = detail.FunctionName; 

      IDbDataParameter outCursor = command.CreateParameter(); 
      oracleDbType.SetValue(outCursor, oracleDbTypeRefCursor, null); 

      outCursor.Direction = detail.HasReturn ? ParameterDirection.ReturnValue : ParameterDirection.Output; 

      command.Parameters.Insert(0, outCursor); 
     } 

     #region IEmbeddedBatcherFactoryProvider Members 

     System.Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass 
     { 
      get { return typeof (OracleDataClientBatchingBatcherFactory); } 
     } 

     #endregion 
    } 

エンドペースト-------