ITPub博客

首页 > 数据库 > 国内数据库 > 循序渐进丨JDBC调用 MogDB 数据库存储过程返回ref_cursor的方法和注意事项

循序渐进丨JDBC调用 MogDB 数据库存储过程返回ref_cursor的方法和注意事项

原创 国内数据库 作者:云和恩墨 时间:2024-08-09 17:58:45 0 删除 编辑

MogDB 数据库在处理存储过程的时候,有时候需要返回结果集,类型为ref_cursor,但有时候可能会报错,而大部分应用程序都是使用Java JDBC。
我们根据这几年的数据库国产化改造经验,通过本文给大家分享一下JDBC调用 MogDB 存储过程返回ref_cursor的方法和注意事项。

01 创建测试用存储过程

该存储过程有两个OUT参数,其中一个返回结果集(sys_refcursor),返回的行数根据第一个参数的长度而定,接下来看看代码:
create or replace procedure test_proc_return_cursor(a varchar,mycur OUT sys_refcursor, total_rows OUT int)

as
begin
total_rows :=length(a);
open mycur for 'select substr(x,1,id),id from (select x,generate_series(1,length(x)) as id from (select :a as x))' using a;
end;


02 创建Java测试代码

import java.sql.*;


public class TestReturnCursor {
   public static void main(String[] args) throws SQLException, ClassNotFoundException {
       TestReturnCursor test = new TestReturnCursor();
       test.runTest();
   }

  private void runTest() throws SQLException, ClassNotFoundException {
      Class.forName( "org.opengauss.Driver");
# 此处替换成准确的ip/port/user/password
      Connection conn = DriverManager.getConnection( "jdbc:opengauss://192.168.56.110:26000/postgres?loggerLevel=off", "testproc", "Test@123");
      conn.setAutoCommit( false);
      CallableStatement cs = (conn.prepareCall ( "{call " + "test_proc_return_cursor(?,?,?)}")) ;
       cs.setString(1, "Test return ref_cursor");
       cs.registerOutParameter(2,Types.REF_CURSOR);
       cs.registerOutParameter(3,Types.INTEGER);

       cs.execute();

       ResultSet rs=(ResultSet)(cs.getObject(2));
       System.out.println( "Total rows:"+cs.getInt(3));

        while(rs.next()){
           System.out.println(rs.getInt(2)+ " "+rs.getString(1));
       }
       rs.close();
       cs.close();
       conn.close();
   }
}

03 编译Java程序

准备好测试用例之后,接下来我们来编译一下:
javac *.java 

java -cp opengaussjdbc.jar:. TestReturnCursor

如下是编译执行的结果输出:

04 Connection对象不设置autocommit=false的情况分析

上述测试代码中,里面有个关键点,Connection对象的autocommit必须设置为false,否则会有如下报错:ERROR: cursor “
原因是在产生ref_cursor的时候,如果没有设置autocommit为false,则内部自动提交,建立的ref_cursor对象在事务外不可见。

05

总结

1、registerOutParameter里,type可以设成Types.REF_CURSOR,也可以设成Types.OTHER;
2、获取结果集时,使用getObject()方法,并将其转换成ResultSet对象。注意CallableStatement.getResultSet()不是这个用途;

3、最关键的一点,Connection对象需要设置autocommit=false。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29715045/viewspace-3024660/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2014-06-19

  • 博文量
    183
  • 访问量
    346702