Luk*_*der 17 oracle stored-procedures jdbc resultset out-parameters
我试图了解使用JDBC从Oracle存储过程/函数获取表数据的不同方法.六种方式如下:
以下是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;
Run Code Online (Sandbox Code Playgroud)
我已成功用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
Run Code Online (Sandbox Code Playgroud)
显然,我很难理解
我似乎无法找到任何关于此的文档,因为每个人总是使用游标而不是表类型.也许是因为它不可能?我更喜欢表类型,因为它们是正式定义的,可以使用字典视图(至少是模式级表类型)来发现.
注意:显然,我可以编写一个包装函数来返回OUT参数和包级表类型.但我更喜欢干净的解决方案.
Vin*_*rat 10
您无法从java访问PLSQL对象(案例2和5 =包级对象),请参阅"java - 在oracle存储过程中传递数组".但是,您可以访问SQL类型(案例1和4).
要从PL/SQL获取OUT参数到java,可以使用Tom Kyte的一个线程中使用OracleCallableStatement 描述的方法.由于您正在检索Object表而不是VARCHAR表,因此您的代码将有一个额外的步骤.
这是一个使用SQL对象表的演示,首先是设置:
SQL> CREATE TYPE t_type AS OBJECT (val VARCHAR(4));
2 /
Type created
SQL> CREATE TYPE t_table AS TABLE OF t_type;
2 /
Type created
SQL> CREATE OR REPLACE PROCEDURE p_sql_type (p_out OUT t_table) IS
2 BEGIN
3 p_out := t_table(t_type('a'), t_type('b'));
4 END;
5 /
Procedure created
Run Code Online (Sandbox Code Playgroud)
实际的java类(dbms_output.put_line用于登录因为我将从SQL调用它,System.out.println如果从java 调用则使用):
SQL> CREATE OR REPLACE
2 AND COMPILE JAVA SOURCE NAMED "ArrayDemo"
3 as
4 import java.sql.*;
5 import oracle.sql.*;
6 import oracle.jdbc.driver.*;
7
8 public class ArrayDemo {
9
10 private static void log(String s) throws SQLException {
11 PreparedStatement ps =
12 new OracleDriver().defaultConnection().prepareStatement
13 ( "begin dbms_output.put_line(:x); end;" );
14 ps.setString(1, s);
15 ps.execute();
16 ps.close();
17 }
18
19 public static void getArray() throws SQLException {
20
21 Connection conn = new OracleDriver().defaultConnection();
22
23 OracleCallableStatement cs =
24 (OracleCallableStatement)conn.prepareCall
25 ( "begin p_sql_type(?); end;" );
26 cs.registerOutParameter(1, OracleTypes.ARRAY, "T_TABLE");
27 cs.execute();
28 ARRAY array_to_pass = cs.getARRAY(1);
29
30 /*showing content*/
31 Datum[] elements = array_to_pass.getOracleArray();
32
33 for (int i=0;i<elements.length;i++){
34 Object[] element = ((STRUCT) elements[i]).getAttributes();
35 String value = (String)element[0];
36 log("array(" + i + ").val=" + value);
37 }
38 }
39 }
40 /
Java created
Run Code Online (Sandbox Code Playgroud)
我们称之为:
SQL> CREATE OR REPLACE
2 PROCEDURE show_java_calling_plsql
3 AS LANGUAGE JAVA
4 NAME 'ArrayDemo.getArray()';
5 /
Procedure created
SQL> EXEC show_java_calling_plsql;
array(0).val=a
array(1).val=b
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30137 次 |
| 最近记录: |