首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate Oracle XMLType问题

NHibernate Oracle XMLType问题
EN

Stack Overflow用户
提问于 2012-04-19 14:54:41
回答 1查看 611关注 0票数 1

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

但是我们得到了错误,因为

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

如何解决这个问题?

EN

回答 1

Stack Overflow用户

发布于 2012-04-19 22:07:11

这是我工作以来的一点,目前我还没有一个工作项目来验证这个问题,然而,我相信这会解决你的问题。

我解决这个问题的方法是对nHibernate项目进行自定义构建。我用下面的编辑编辑了OracleDataClientDriver.cs文件。你应该注意到,我刚刚下载了这个文件的当前版本,自从我修复后,它在过去的两年里发生了轻微的变化。如果您从nHibernate存储库获取该文件的当前版本,并使用我将要粘贴的代码对该文件进行dif,您将看到这些更改。我的更改在行号上(根据我的编辑) 26,45,82-85。

修复的主题是,我必须添加一个从nHibernate映射文件类型到Oracle Data Type for XML的映射。Oracle驱动程序将处理这种类型,但是在nHibernate中缺少使用它的逻辑。下面是解决这个问题的方法。

开始粘贴

代码语言:javascript
复制
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
    }

结束粘贴

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10223023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档