【问题标题】:NHibernate Oracle XMLType issueNHibernate Oracle XMLType 问题
【发布时间】:2012-04-19 06:54:41
【问题描述】:

我们在 oracle 10g 数据库中有一个函数,它返回一个 XMLTYPE 值。我们正在尝试使用命令对象中的 ParameterDirection.ReturnValue 从函数中获取返回值。

但是我们遇到了错误

System.Data.OracleClient.OracleException (0x80131938):ORA-06550:第 1 行,第 27 列: PLS-00382:表达式类型错误 ORA-06550:第 1 行,第 7 列: PL/SQL:语句被忽略

如何解决?

【问题讨论】:

    标签: c# nhibernate oracle10g


    【解决方案1】:

    自从我从事这个工作以来已经有一段时间了,目前我没有一个工作项目来验证这个问题,但是,我相信这会解决你的问题。

    我解决这个问题的方法是自定义构建 nHibernate 项目。我用下面的编辑编辑了 OracleDataClientDriver.cs 文件。您应该注意,我刚刚下载了该文件的当前版本,并且在我进行修复后的过去 2 年中它略有变化。如果您从 nHibernate 存储库获取文件的当前版本,并使用我要粘贴的代码对文件进行区分,您将看到更改。我的更改位于第 26、45、82-85 行(根据我的编辑)。

    修复的主题是我必须添加一个从 nHibernate 映射文件类型到 XML 的 Oracle 数据类型的映射。 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
        }
    

    结束粘贴-------

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 1970-01-01
      相关资源
      最近更新 更多