【问题标题】:Oracle Stored Procedure with out parameter using Nhibernate使用 Nhibernate 没有参数的 Oracle 存储过程
【发布时间】:2009-11-26 17:25:16
【问题描述】:

如何在 .net 代码中访问 oracle 存储过程的 out 参数的值 - 通过 Nhibernate 调用 Oracle 存储过程?

示例工作代码会有所帮助。

【问题讨论】:

    标签: oracle nhibernate stored-procedures


    【解决方案1】:

    您必须使用最新版本的 NHibernate (2.1.2)。

    <sql-query name="ReturnSomethig" callable="true">
       <return class="Somethig" />
       { call ReturnSomethig(:someParameter) }
    </sql-query>
    

    Oracle 存储过程需要有第一个参数作为 out sys_refcursor 参数。

    你可以这样调用命名查询:

    IQuery query = currentSession.GetNamedQuery("ReturnSomethig");
    query.SetInt64("someParameter", someParameter);
    var somethig = query.List<Somethig>();
    

    它会起作用的。

    【讨论】:

    • 我无法让它工作。当我下载源代码时,我实际上不得不利用这篇文章 (forum.hibernate.org/viewtopic.php?f=25&t=999056) 进行一些更改。 2.1.2 版本也是如此。
    • 当时我们没有使用 refcursor 来解决我们的问题,但是,我觉得这本来可以解决我的问题。因此,接受它。 请参考上面 Blake 的链接。
    【解决方案2】:

    我尝试了 2.1.2 库,但运气不佳。我实际上必须根据this article 对库进行一些修改。如果你走这条路,你需要确保你使用的是 Oracle.DataAccess dll,因为它不能与 System.DataAccess.OracleClient dll 一起使用。

    【讨论】:

      【解决方案3】:

      在研究从 NHibernate 获取参数时,我发现各种链接表明,要获取存储的 proc out 参数值(而不是使用 refcursor),您需要在代码中构造命令,而不是使用 XML 映射文件。

      但是我发现很难在网上找到一个完整的工作示例。这不是一个漂亮的解决方案,但我会发布以防它对某人有所帮助。

      1. Oracle 存储过程示例:

        create or replace PACKAGE BODY MY_PACKAGE AS
        
          PROCEDURE add_one
          (
            p_out out number,
            p_in in number
          ) AS
          BEGIN
            select p_in + 1 into p_out from dual;
          END add_one;
        
        END MY_PACKAGE;
        
      2. 示例 C# 代码,其中 sessionFactory 是 NHibernate ISessionFactory

        using (var session = sessionFactory.OpenSession())
        using (var transaction = session.BeginTransaction())
        {
            var command = session.Connection.CreateCommand();
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = "MY_PACKAGE.add_one";
        
            var parmOut = command.CreateParameter();
            parmOut.ParameterName = "p_out";
            parmOut.DbType = DbType.Decimal;
            parmOut.Direction = ParameterDirection.Output;
            command.Parameters.Add(parmOut);
        
            var parmIn = command.CreateParameter();
            parmIn.ParameterName = "p_in";
            parmIn.DbType = DbType.Decimal;
            parmIn.Direction = ParameterDirection.Input;
            parmIn.Value = 67;
            command.Parameters.Add(parmIn);
        
            transaction.Enlist(command);
            command.ExecuteNonQuery();
        
            int sixtyEight = (int) (decimal) parmOut.Value;
        }
        

      【讨论】:

        【解决方案4】:

        参见 Richard Brown 的 this comment。一些示例代码可以在 here 找到。
        不幸的是我无法测试它,所以我不知道它是否有效。

        【讨论】:

          【解决方案5】:

          迟来的回复。

          对于 oracle,nHibernate 不支持 out 参数,除非它是游标。如果您只想要一个标量值,解决方法是使用 oracle 函数包装您的存储过程。

          那么你可以这样做

            <sql-query name="TestOracleFunction" callable="true">
              <return-scalar column="MyOutputValue" type="String" />
              <![CDATA[
              select MyOracleFunction as MyOutputValue from dual
            ]]>
            </sql-query>
          

          这行得通!

          【讨论】:

            猜你喜欢
            • 2012-05-12
            • 1970-01-01
            • 1970-01-01
            • 2011-01-11
            • 2010-10-12
            • 2013-11-17
            • 2013-11-02
            • 2019-10-29
            • 2013-03-04
            相关资源
            最近更新 更多