sys_refcursor游标使用方法

  SQL报错
内容纲要

概要描述


在开发中我需要在Procedure A中打开一个动态SQL的游标,并返回此cursor;然后用Procedure B去call A存储过程,再对返回的cursor进行操作,这个时候需要通过sys_refcursor游标在过程中返回结果集。

下面的例子简单介绍了sys_refcursor的使用方法。

详细说明


创建样例表并插入数据

CREATE  TABLE emp_torc(
  empno decimal(38,0) DEFAULT NULL, 
  ename string DEFAULT NULL, 
  job string DEFAULT NULL, 
  mgr decimal(38,0) DEFAULT NULL, 
  hiredate timestamp DEFAULT NULL, 
  sal decimal(38,0) DEFAULT NULL, 
  comm decimal(38,0) DEFAULT NULL, 
  deptno decimal(38,0) DEFAULT NULL
)
CLUSTERED BY ( 
  empno) 
INTO 3 BUCKETS
STORED AS ORC_TRANSACTION;

BATCHINSERT INTO emp_torc BATCHVALUES(
VALUES (7521,'WARD','SALESMAN',7698,'1981-01-22',1250,500,30),
VALUES (7566,'JONES','MANAGER',7839,'1981-01-02',2975,NULL,20),
VALUES (7698,'BLAKE','MANAGER',7839,'1981-01-01',2850,NULL,30),
VALUES (7782,'CLARK','MANAGER',7839,'1981-01-09',2450,NULL,10),
VALUES (7788,'SCOTT','ANALYST',7566,'1987-01-13',3000,NULL,20),
VALUES (7839,'KING','PRESIDENT',NULL,'1981-01-17',5000,NULL,10),
VALUES (7902,'FORD','ANALYST',7566,'1981-01-03',3000,NULL,20),
VALUES (7369,'SMITH','CLERK',7902,'1980-01-17',800,NULL,20),
VALUES (7654,'MARTIN','SALESMAN',7698,'1981-01-28',1250,1400,30),
VALUES (7876,'ADAMS','CLERK',7788,'1987-01-13',1100,NULL,20),
VALUES (7900,'JAMES','CLERK',7698,'1981-01-03',950,NULL,30),
VALUES (7499,'ALLEN','SALESMAN',7698,'1981-01-20',1600,300,30),
VALUES (7844,'TURNER','SALESMAN',7698,'1981-01-08',1500,0,30),
VALUES (7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10)
);

以下面的语句为例:

CREATE OR REPLACE PROCEDURE pcx_dgzq_test_all_user(v_job in string,cur OUT sys_refcursor) is
begin
open cur for
SELECT * FROM emp_torc WHERE job=v_job;
end;

pl/sql调用方式

DECLARE
    V_SYS_REFCURSOR_ROWS SYS_REFCURSOR;
    V_ROWS           DEFAULT.emp_torc%ROWTYPE;
BEGIN
    pcx_dgzq_test_all_user('SALESMAN', V_SYS_REFCURSOR_ROWS);
    LOOP
        FETCH V_SYS_REFCURSOR_ROWS
            INTO V_ROWS;
        EXIT WHEN V_SYS_REFCURSOR_ROWS%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(V_ROWS.ENAME);
    END LOOP;
    CLOSE V_SYS_REFCURSOR_ROWS;
END;

file

存储过程调用方式

CREATE OR REPLACE PROCEDURE pcx_dgzq_test_get_name(v_job IN STRING)
AS 
    V_SYS_REFCURSOR_ROWS SYS_REFCURSOR;
    V_ROWS           DEFAULT.emp_torc%ROWTYPE;
BEGIN
    pcx_dgzq_test_all_user(v_job, V_SYS_REFCURSOR_ROWS);
    LOOP
        FETCH V_SYS_REFCURSOR_ROWS
            INTO V_ROWS;
        EXIT WHEN V_SYS_REFCURSOR_ROWS%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(V_ROWS.ENAME);
    END LOOP;
    CLOSE V_SYS_REFCURSOR_ROWS;
END
CALL pcx_dgzq_test_get_name('SALESMAN');

file

jdbc访问输出参数类型为sys_refcursor的简单示例

该方法同pl/sql调用方式,而非存储过程调用方式

import java.sql.*;
public class JDBCexample {
    private static String driverName = "org.apache.hive.jdbc.HiveDriver";

    public static void main(String[] args) throws SQLException {
        try {
            Class.forName(driverName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.exit(1);
        }
        //Hive2 JDBC URL with LDAP
        String jdbcURL = "jdbc:hive2://172.22.23.1:10000/default";
        String user = "hive";
        String password = "123456";
        ResultSet rs = null;
        Connection conn = DriverManager.getConnection(jdbcURL, user, password);
        CallableStatement cbstmt = conn.prepareCall("call pcx_dgzq_test_all_user(?,?)");
        cbstmt.setString(1, "SALESMAN");
        cbstmt.registerOutParameter(2, -10);
        cbstmt.execute();
        rs = (ResultSet) cbstmt.getObject(2);
        System.out.println();
        while (rs.next()) {
            System.out.println(rs.getString(2));
        }
        rs.close();
        cbstmt.close();
        conn.close();
    }
}

file

这篇文章对您有帮助吗?

平均评分 0 / 5. 次数: 0

尚无评价,您可以第一个评哦!

非常抱歉,这篇文章对您没有帮助.

烦请您告诉我们您的建议与意见,以便我们改进,谢谢您。