【发布时间】:2011-09-18 14:55:13
【问题描述】:
我试图了解使用 JDBC 从 Oracle 存储过程/函数获取表数据的不同方法。这六种方式分别是:
- 将架构级表类型作为 OUT 参数返回的过程
- 将包级表类型作为 OUT 参数返回的过程
- 将包级游标类型作为 OUT 参数返回的过程
- 函数返回模式级表类型
- 函数返回包级表类型
- 函数返回包级游标类型
以下是 PL/SQL 中的一些示例:
-- schema-level table type
CREATE TYPE t_type AS OBJECT (val VARCHAR(4));
CREATE TYPE t_table AS TABLE OF t_type;
CREATE OR REPLACE PACKAGE t_package AS
-- package level table type
TYPE t_table IS TABLE OF some_table%rowtype;
-- package level cursor type
TYPE t_cursor IS REF CURSOR;
END library_types;
-- and example procedures:
CREATE PROCEDURE p_1 (result OUT t_table);
CREATE PROCEDURE p_2 (result OUT t_package.t_table);
CREATE PROCEDURE p_3 (result OUT t_package.t_cursor);
CREATE FUNCTION f_4 RETURN t_table;
CREATE FUNCTION f_5 RETURN t_package.t_table;
CREATE FUNCTION f_6 RETURN t_package.t_cursor;
我已经成功用JDBC调用了3、4、6:
// Not OK: p_1 and p_2
CallableStatement call = connection.prepareCall("{ call p_1(?) }");
call.registerOutParameter(1, OracleTypes.CURSOR);
call.execute(); // Raises PLS-00306. Obviously CURSOR is the wrong type
// OK: p_3
CallableStatement call = connection.prepareCall("{ call p_3(?) }");
call.registerOutParameter(1, OracleTypes.CURSOR);
call.execute();
ResultSet rs = (ResultSet) call.getObject(1); // Cursor results
// OK: f_4
PreparedStatement stmt = connection.prepareStatement("select * from table(f_4)");
ResultSet rs = stmt.executeQuery();
// Not OK: f_5
PreparedStatement stmt = connection.prepareStatement("select * from table(f_5)");
stmt.executeQuery(); // Raises ORA-00902: Invalid data type
// OK: f_6
CallableStatement call = connection.prepareCall("{ ? = call f_6 }");
call.registerOutParameter(1, OracleTypes.CURSOR);
call.execute();
ResultSet rs = (ResultSet) call.getObject(1); // Cursor results
很明显,我很难理解
- 如何从存储过程中的 OUT 参数中检索架构级别和包级别的表类型
- 如何从存储的函数中检索包级表类型
我似乎找不到任何关于此的文档,因为每个人总是使用游标而不是表类型。也许是因为不可能?不过,我更喜欢表类型,因为它们是正式定义的,并且可以使用字典视图(至少是模式级别的表类型)来发现。
注意:显然,我可以编写一个包装函数,返回 OUT 参数和包级表类型。但我更喜欢干净的解决方案。
【问题讨论】:
-
您是否期望结果是表的结构,即 column1 varchar2 (100)、column2 varchar2 (50)...?或者你想看'IS REF CURSOR'或类似的东西吗?
-
我获得的有关光标/表格类型的信息越多越好。但无论如何,我认为使用 JDBC 的
ResultSet.getMetaData()我可以即时发现这些信息 -
@LukasEder mysql 怎么样?我需要使用 jdbc 在 java 中调用一个过程,它返回一个表......是否可以通过 jdbc 使用 mysql?
-
@Jack-in-the-box:请提出一个新问题。这是一个非常具体的 Oracle 相关问题
-
@LukasEder 谢谢。前几天我问过:)here
标签: oracle stored-procedures jdbc resultset out-parameters