JDBCを使用してOracleストアドプロシージャ/関数からテーブルデータを取得するさまざまな方法を理解しようとしています。6つの方法は次のとおりです。
- スキーマレベルのテーブルタイプを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パラメーターとパッケージレベルのテーブルタイプを返すラッパー関数を作成できます。しかし、私はクリーンなソリューションを好みます。