代码之家  ›  专栏  ›  技术社区  ›  Richard Nienaber

Oracle存储过程、系统引用光标和nHibernate

  •  7
  • Richard Nienaber  · 技术社区  · 16 年前

    我有一个旧的Oracle(10.2g)数据库正在连接,我想使用nhibernate(2.0.1)从存储过程中返回对象。有问题的存储过程使用系统指针返回结果。根据 documentation 这应该是可行的,但我发现 few posts 在互联网上有不同的建议。

    这是我的解释代码:

    映射文件:

    <?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;
    
    5 回复  |  直到 13 年前
        1
  •  1
  •   Cody Gray    13 年前

    据我所知,这是几年前我在与Oracle合作时发现的一个bug,我已经在NH Tracker中跟踪到了这个问题,并在2.1.1ga版本中得到了修复;您能确认这是您遇到的同一个问题吗? https://nhibernate.jira.com/browse/NH-847

        2
  •  2
  •   Deepfreezed    14 年前

    这是多么的痛苦啊。这终于奏效了。我把存储过程变成了一个函数。函数返回了sys-refcursor。使用与下面的op和name查询类似的映射。

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

    Link

        3
  •  1
  •   Rob M    16 年前

    根据 this page 您应该使用call而不是exec。我没试过,所以YMMV。

        4
  •  1
  •   No AI now No AI ever    16 年前

    在休眠状态下,您会声明一个返回类型,但Oracle过程不会返回任何内容。如果您将其更改为返回ref光标的函数,它可能会正常工作。另外,我认为call是正确的语法。exec是一个sql*plus命令,不是真正的sql语句。

        5
  •  1
  •   bananafish2k    14 年前

    今天我遇到了同样的问题。对于我们来说,修复方法是使用“call”而不是“exec”,在过程调用中添加圆括号“()”,并用大括号“”括住调用:

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