【问题标题】:Oracle stored procedures, SYS_REFCURSOR and NHibernateOracle 存储过程、SYS_REFCURSOR 和 NHibernate
【发布时间】:2010-10-12 18:13:53
【问题描述】:

我有一个要连接的旧版 Oracle (10.2g) 数据库,我想使用 NHibernate (2.0.1) 从存储过程中返回对象。有问题的存储过程使用 SYS_REFCURSOR 返回结果。根据documentation,这应该是可行的,但我在互联网上发现了一个fewposts,表明并非如此。

这是我的解释代码:

映射文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
assembly="OracleStoredProcedures" namespace="OracleStoredProcedures">
    <class name="Person" mutable="false">
        <id name="PersonCode" type="AnsiString" column="PERSONCODE">
            <generator class="assigned" />
        </id>
        <property name="Name" type="String" column="PERSON_NAME" />
        <property name="Surname" type="String" column="PERSON_SURNAME" />
    </class>

    <sql-query name="getpeople">
        <return class="Person" />

        EXEC RS_DB.GETPERSONTEST 

    </sql-query>
</hibernate-mapping>

存储过程:

CREATE OR REPLACE PROCEDURE RS_DB.GETPERSONTEST (
   io_cursor   IN OUT   sys_refcursor
)
IS
BEGIN
   OPEN io_cursor FOR
      SELECT PERSONCODE, PERSON_NAME, PERSON_SURNAME
      FROM PEOPLE

END GETPERSONTEST;

【问题讨论】:

    标签: c# oracle nhibernate stored-procedures


    【解决方案1】:

    这是多么痛苦啊。这终于奏效了。我把存储过程变成了一个函数。函数返回 sys_refcursor。使用与 OP 和名称查询类似的映射,如下所示。

    <sql-query name="getpeople">
     <return class="Person" />
    
     { ? = call RS_DB.GETPERSONTEST }
    </sql-query>
    

    Link

    【讨论】:

    • 我遇到了同样的问题,我无法让这个解决方案发挥作用。你能提供任何代码吗?
    • 通过映射返回 sys_refcursor 的函数的索引超出范围 { ? = 在 NHibernate 4.0.4 上调用 RS_DB.GETPERSONTEST(?, ?) }
    【解决方案2】:

    据我所知,这是我几年前在使用 oracle 时也发现的一个错误,我已经在 NH 跟踪器中追踪了该问题,并且在 2.1.1GA 版本上已修复;你能确认这和你有同样的问题吗? https://nhibernate.jira.com/browse/NH-847

    【讨论】:

    • 好的,终于可以在我们的代码中查看这个了。我写了一个解决方法,但至少可以说是笨拙的。我们已经升级到 NHibernate 3.0 并使用提供的链接中的语法 ({ callemploysForRegion(:regionCode) }) 并且它有效!感谢您迟到的答复:)。
    【解决方案3】:

    根据this page,您应该使用 CALL 而不是 EXEC。这个我没试过,所以YMMV。

    【讨论】:

      【解决方案4】:

      在您的休眠中,您声明了一个返回类型,但 Oracle 过程不返回任何内容。也许如果您将其更改为返回 ref 光标的函数,它将正常工作。另外,我相信 CALL 是正确的语法。 EXEC 是一个 SQL*Plus 命令,并不是真正的 SQL 语句。

      【讨论】:

        【解决方案5】:

        我今天遇到了同样的问题。对我们来说,解决方法是使用“CALL”而不是“EXEC”,将圆括号“()”添加到过程调用中,并将调用包装在花括号“{}”中:

        <sql-query name="getpeople">
            <return class="Person" />
        
            { CALL RS_DB.GETPERSONTEST() }
        
        </sql-query>
        

        【讨论】:

          猜你喜欢
          • 2017-08-18
          • 2011-01-11
          • 1970-01-01
          • 1970-01-01
          • 2018-09-03
          • 1970-01-01
          • 1970-01-01
          • 2021-06-22
          • 1970-01-01
          相关资源
          最近更新 更多