Java 我可以在HSQLDB中使用CURSOR类型的OUT参数吗?

Java 我可以在HSQLDB中使用CURSOR类型的OUT参数吗?,java,oracle,unit-testing,stored-procedures,hsqldb,Java,Oracle,Unit Testing,Stored Procedures,Hsqldb,我有一个java web项目,它通过存储过程与Oracle数据库进行通信。当存储过程需要返回记录集时,我让存储过程接受SYS\u REFCURSOR类型的OUT参数。然后Java代码迭代记录集以读取值。我正在尝试对DOA层进行单元测试,并开始使用HSQLDB模拟数据库,但似乎不可能在HSQLDB中有一个存储的proc,并去掉游标参数。我以前从未使用过HSQLDB,所以请原谅我对如何使用它的无知。 以前有人处理过这个问题吗? 我觉得我的选择是: 使用MS SQL,它实际上允许存储过程执行selec

我有一个java web项目,它通过存储过程与Oracle数据库进行通信。当存储过程需要返回记录集时,我让存储过程接受SYS\u REFCURSOR类型的OUT参数。然后Java代码迭代记录集以读取值。我正在尝试对DOA层进行单元测试,并开始使用HSQLDB模拟数据库,但似乎不可能在HSQLDB中有一个存储的proc,并去掉游标参数。我以前从未使用过HSQLDB,所以请原谅我对如何使用它的无知。 以前有人处理过这个问题吗? 我觉得我的选择是:

  • 使用MS SQL,它实际上允许存储过程执行select操作,而不必使用OUT SYS_REF游标将数据传递回Java代码。就我而言,这更像是一种愿望,我的公司不允许我使用MS SQL:(
  • 在PL/SQL中找到一种方法,使存储过程以Java调用方可以使用的方式返回不带OUT参数的记录
  • 寻找HSQLDB的替代方案,让我在单元测试期间模拟存储过程,其行为更像Oracle
  • 不要费心对DOA层进行单元测试。这似乎是我将要结束的地方,这并不重要,因为DOA层中几乎没有任何业务逻辑在测试中有价值,这更多的是尝试改进我的代码覆盖率统计数据
  • 以下是对存储过程的典型调用,仅供参考:

       private static final RowMapper<MyRecord> RECORD_ROW_MAPPER=
            (rs, i) -> new MyRecord(rs.getInteger("OWNER_ID"),
                                    rs.getString("NAME"), 
                                    rs.getString("DESCRIPTION"));
    
       private static final SimpleJdbcCall getRecordProcCall = new SimpleJdbcCall(dataSource)
                                  .withSchemaName("app_data")
                                  .withProcedureName("getMyRecords")
                                  .returningResultSet("OUT_RECORD", RECORD_ROW_MAPPER);
    
       public ArrayList<MyRecord> getMyRecords(int ownerId) {
          SqlParameterSource in = new MapSqlParameterSource()
                                  .addValue("IN_OWNER_ID", ownerId);
          return getRecordProcCall.executeFunction(ArrayList.class, in);
       }
    

    我知道我可以用direct SQL来做这个简单的例子,而不使用存储过程,但在本文中展示我如何访问数据库只是一个简单的例子。实际上,我正在做大量的工作,最好在存储过程中完成。

    你可以从HSQLDB存储过程中获取光标

    CREATE PROCEDURE getMyRecords (
     IN_OWNER_ID IN  NUMBER
    ) 
     BEGIN ATOMIC
      DECLARE MYCURSOR CURSOR FOR RETURN FOR
       SELECT OWNER_ID, NAME, DESCRIPTION
       FROM MY_RECORD
       WHERE OWNER_ID = IN_OWNER_ID;
      OPEN MYCURSOR;
     END
    
    在JDBC方面,它应该通过在调用getResultSet()和getMoreResults()之后获取一个ResultSet来工作

    顺便说一句,您可以通过创建一个伪类型来模拟过程签名,例如

    CREATE TYPE SYS_REFCURSOR AS INT;
    

    并使用与原始过程相同的签名。

    您可以从HSQLDB存储过程中获取游标

    CREATE PROCEDURE getMyRecords (
     IN_OWNER_ID IN  NUMBER
    ) 
     BEGIN ATOMIC
      DECLARE MYCURSOR CURSOR FOR RETURN FOR
       SELECT OWNER_ID, NAME, DESCRIPTION
       FROM MY_RECORD
       WHERE OWNER_ID = IN_OWNER_ID;
      OPEN MYCURSOR;
     END
    
    在JDBC方面,它应该通过在调用getResultSet()和getMoreResults()之后获取一个ResultSet来工作

    顺便说一句,您可以通过创建一个伪类型来模拟过程签名,例如

    CREATE TYPE SYS_REFCURSOR AS INT;
    

    并使用与原始过程相同的签名。

    从Oracle 12c版本1(12.1)开始,该软件包包括将已执行语句的结果返回到客户端应用程序的过程,类似于MS SQL Server过程隐式返回记录集的方式


    ORACLE-BASE博客的Tim Hall在

    上发表了一篇很好的文章,从ORACLE 12c发行版1(12.1)开始,该软件包包括一个过程,该过程将执行语句的结果返回给客户端应用程序,类似于MS SQL Server过程隐式返回记录集的方式


    ORACLE-BASE博客的Tim Hall在

    上发表了一篇很好的帖子,如果您使用ORACLE 12c,您可以利用它来模拟MS SQL从存储过程返回的方式。听起来它会起作用,我必须仔细阅读。谢谢!Sentinel,这很有效。如果您重新提交此答案,我将接受它作为答案。如果您使用Oracle 12c您可以利用它来模拟MS SQL从存储过程返回的方式。这听起来很有效,我必须仔细阅读。谢谢!Sentinel,这很有效。如果您重新提交此作为答案,我将接受它作为答案。