Oracle JDBC从过程中获取SYS_REFCURSOR

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle JDBC从过程中获取SYS_REFCURSOR相关的知识,希望对你有一定的参考价值。

我正在使用Oracle 12g,并试图从ResultSet获得SYS_REFCURSOR

我有一个带有以下签名的程序:

CREATE OR REPLACE PROCEDURE proc_search(user IN VARCHAR2, res OUT SYS_REFCURSOR)

这是我正在使用的Java JDBC代码:

try {
    CallableStatement cstmt = con.prepareCall("exec proc_search(?, ?)");
    cstmt.setString(1, login);
    cstmt.registerOutParameter(2, Types.REF);
    cstmt.execute();
    ResultSet rs = (ResultSet)cstmt.getObject(2);

    while (rs.next()) {
        System.out.println(rs.getString(1));
    }
} catch (Exception e) {
    System.err.println(e);
    e.printStackTrace();
}

但是,我收到以下错误:

java.sql.SQLException:ORA-03115:不支持的网络数据类型或表示形式

答案

首先,getCursor方法应该用于SYS_REFCURSOR而不是getObject

其次,prepareCall应该有BEGINEND

代码段

try {
    CallableStatement cstmt = con.prepareCall("BEGIN proc_search(?, ?); END;");
    cstmt.setString(1, login);
    cstmt.registerOutParameter(2, OracleTypes.CURSOR); 
    cstmt.execute();
    ResultSet rs = ((OracleCallableStatement)cstmt).getCursor(2);

    while (rs.next()) {
        System.out.println(rs.getString("name"));
    }
} catch (Exception e) {
    System.err.println(e);
    e.printStackTrace();
}

作为旁注,必须有一个finally块来关闭Connection,CallableStatement,ResultSet等。

finally {
    try {
        if (con != null)
            con.close();

        if (cstmt!= null)
            cstmt.close();

        if (rs!= null)
            rs.close();

    } catch (SQLException sqlexc) {
        sqlexc.printStackTrace();
    }
}

更新1

使用CallableStatement

    Connection conn = null;
    CallableStatement callableStatement = null;
    ResultSet rs = null;

    try {
        conn = getconn();
        callableStatement = conn.prepareCall("{call proc_search(?, ?)}");    
        callableStatement.setString(1, login);
        callableStatement.registerOutParameter(2, OracleTypes.CURSOR);

        callableStatement.executeUpdate();    

        rs = (ResultSet) callableStatement.getObject(2);    
        while (rs.next()) {
            String userid = rs.getString("name");
        }

    } catch (SQLException e) {

        System.out.println(e.getMessage());
        e.printStackTrace();

    } finally {

        if (rs != null) {
            rs.close();
        }

        if (callableStatement != null) {
            callableStatement.close();
        }

        if (conn != null) {
            conn.close();
        }

    }

    }

以上是关于Oracle JDBC从过程中获取SYS_REFCURSOR的主要内容,如果未能解决你的问题,请参考以下文章

使用 JDBC 的 Oracle 临时表计数错误

如何从 JDBC 创建或替换 Oracle 中的过程?

如何从 Oracle 中的 JDBC 批量插入中获取生成的密钥?

如何从 Java JDBC 中的 callableStatement 获取滚动不敏感的结果集?

如何使用 jdbc 从 Oracle 中的结果集中获取模式名称?

从 Oracle DB 获取可滚动的结果集