如何從 Java 存儲過程將 JDBC ResultSet 作爲 Ref Cursor 返回

如何從 Java 存儲過程將 JDBC ResultSet 作爲 Ref Cursor 返回

日期:2003 年 3 月 3 日

在閱讀此方法文檔以後,您應該能夠:

  • 創建將 JDBC 結果集作爲 REF CURSOR 返回的 Java 存儲過程

  • 創建 Java 存儲過程的調用規範

簡介

本文檔演示如何從 Java 存儲過程將 JDBC ResultSet 作爲 REF CURSOR 返回。JDBC ResultSet 是一個表示數據庫的數據表,通常通過執行查詢數據庫的語句產生該表。REF CURSORPL/SQL 中相應的類型。Java 存儲過程的調用規範將 ResultSet 映射到 REF CURSOR。在 Oracle9i 之前,不可能從 Java 存儲過程直接返回一個 ResultSet,因爲沒有定義表單 ResultSet->REF CURSOR 的映射。Oracle9i 增加了此映射,允許從函數返回 ResultSet 或將其作爲 OUT 參數傳到某個過程。但它仍不支持逆向映射 (REF CURSOR->ResultSet),因此當前版本的數據庫仍然不支持 IN 和 IN OUT 參數。

在本方法指南中,我們擁有兩個 Java 存儲過程。Java 存儲過程 getEmployees()SCOTT 模式中 EMP 表的所有列裝入 ResultSet 中並將其返回。Java 存儲過程 getDepartments(ResultSet[] rout)ResultSet 對象作爲 OUT 參數並將 DEPT 表的所有列裝入此 ResultSet 對象中。

軟件需求

  • Oracle9i Database 版本 9.0.1 或更高版本。您可從 Oracle 技術網下載 Oracle9i 數據庫。

  • JDK1.2.x 或以上版本。可以從此處下載。

說明

首先必須創建 Java 存儲過程。以下爲代碼段。單擊此處查看完整的 java 代碼。

在 Java 存儲過程中,可獲得默認的服務器端對數據庫的連接。默認情況下,由服務器端 JDBC 驅動程序創建的語句產生不能轉換爲 REF CURSORResultSet 對象。要將 ResultSet 作爲 REF CURSOR 返回,必須以特殊方式創建 StatementPreparedStatement,即必須在創建該語句之前對 Connection 調用 setCreateStatementAsRefCursur(true)。如果不能在創建 ResultSet 並將其作爲 REF CURSOR 返回之前調用 setCreateStatementAsRefCursor(true),則在執行 Java 存儲過程時將會導致出現下列錯誤消息:

ORA-00932:inconsistent datatypes

一旦對此 Connection 對象調用了 setCreateStatementAsRefCursor(true),由對此連接的查詢返回的所有 ResultSet 可以轉換爲 REF CURSOR

Java 存儲過程列表 1

public static ResultSet getEmployees() {
............. ............. // Obtain default connection
Connection conn = new OracleDriver().defaultConnection();
// Create any subsequent statements as a REF CURSOR
((OracleConnection)conn).setCreateStatementAsRefCursor(true); // Create the statement Statement stmt = conn.createStatement(); // Query all columns from the EMP table ResultSet rset = stmt.executeQuery("select * from emp"); // Return the ResultSet (as a REF CURSOR)
return rset;
...........
...........

 

在上面的 Java 存儲過程中,通過對默認服務器連接調用 setCreateStatementAsRefCursor(true),默認服務器連接設置爲返回可以轉換爲 REF CURSOR 的 ResultSet。然後查詢 EMP 表中的所有行並返回 ResultSet。

Java 存儲過程列表 2

public static void getDepartments( ResultSet[] rout ) {
............
............
// Obtain the default connection
Connection conn = new OracleDriver().defaultConnection(); // Create any subsequent statements as a REF CURSOR
((OracleConnection)conn).setCreateStatementAsRefCursor(true); // Create the statement
Statement stmt = conn.createStatement(); // do a simple query
ResultSet rset = stmt.executeQuery("select * from dept"); // return the ResultSet (as a REF CURSOR)
rout[0] = rset;
...........
...........

上面的 Java 存儲過程 getDepartments( ResultSet[] rout ) 查詢 DEPT 表的所有行並在 OUT 參數中返回 ResultSet

如要觀看應用程序的運行,請將 Java 類加載到您數據庫的 SCOTT 模式中。

>loadjava -thin -user scott/tiger@<hostname>:<port>:<SID> -resolve -verbose RefCursor.java

其中:

<hostname> 安裝數據庫的主機名稱
<port> 數據庫的 TNS 監聽器端口
<SID> 數據庫名稱

例如:

>loadjava -thin -user scott/[email protected]:1521:otn9idb -resolve -verbose RefCursor.java

然後創建 Java 存儲過程的調用規範。連接到 SCOTT/TIGER 用戶並在 SQL 提示符處執行以下代碼

create or replace package refcurpkg is
type refcur_t is ref cursor;
end refcurpkg;
/


create or replace function getemps return refcurpkg.refcur_t is
language java name 'RefCursor.getEmployees() return java.sql.ResultSet'; 
/

create or replace procedure getdepts(cur OUT refcurpkg.refcur_t) is
language java name 'RefCursor.getDepartments(java.sql.ResultSet[])';
/

在上面的列表中,在包 refcurpkg 中創建了一個新的類型作爲 REF CURSOR 類型。然後創建 Java 存儲過程的調用規範。返回 REF CURSOR 的調用規範 getemployees 發佈 Java 存儲過程 getEmployees()。由 Java 存儲過程 getEmployees() 返回的 ResultSet 映射到 REF CURSOR

調用規範 getdepts 發佈 Java 存儲過程 getDepartments,並將 OUT 參數 REF CURSOR 映射到 ResultSet

現在可以通過在 SQL 提示符處執行以下代碼來測試 Java 存儲過程

SQL>variable x refcursor
SQL>execute :x := getemps;
SQL>print x

此操作將打印 SCOTT 模式EMP 表的內容。  

 

SQL>execute getdepts(:x);
SQL>print x

此操作將打印 SCOTT 模式中 DEPT 表的內容。

資源

總結

本文說明了如何創建將 JDBC ResultSet 作爲 REF CURSOR 返回的 Java 存儲過程,以及如何爲Java 存儲過程編寫調用規範。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章