最近CSDN上有比較多的朋友問到java與oracle預存程序/函數的互動方面的問題。本人也是一步步學起來的,在之前也碰到過類似的問題,經常一頭霧水。但現在某些東西似乎是有點入門的味道了,覺得應該寫點什麼總結一下,方便福士,也是為了自己尋找方便。就準備寫一個系列。
嗯,因為是原創,可能代碼存在一些錯誤或者不足,還希望大家諒解並指出來。但可以負責任的說一句:本人的以下代碼都是測試通過的,可以直接^C^V用。好了,廢話不多說,直接來第一篇。
oracle的串連類
這個在後續的所有java代碼中都會用到,本來不想寫的,但懶得每個類中都這麼getConnection一下,所以弄了這個。另外,類所在的package也就不改了,請要用的朋友相應的修改吧,後續的各篇也是如此,這裡就不過多羅嗦了。
package test.oracle.conn;<br />import java.sql.Connection;<br />import java.sql.DriverManager;<br />public class OConnection {<br />public static Connection getConn() {<br />String URL = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL";<br />String user = "cartoon";// 這裡替換成你自已的資料庫使用者名稱<br />String password = "oracle";// 這裡替換成你自已的資料庫使用者密碼<br />Connection connection = null;<br />try {<br />Class.forName("oracle.jdbc.driver.OracleDriver");<br />System.out.println("類執行個體化成功!");<br />connection = DriverManager.getConnection(URL, user, password);<br />System.out.println("建立串連對像成功!");</p><p>} catch (Exception err) {<br />err.printStackTrace();<br />return null;<br />}<br />return connection;<br />}<br />}<br />
1varchar2、number數組.sql
--為了保證寫出來的都是可以啟動並執行,所以每次建立表、類型等等,都先drop一下。第一次啟動並執行朋友,可能會發現drop語句報×××不存在,可以忽略。引號
drop table T_VarcharArray;
create table T_VarcharArray(
id number(10),
name varchar2(100)
);
drop type T_VARCHAR;
--建立一個與T_VarcharArray的name同類型的不定長數組的引定義
create or replace type T_VARCHAR as table of varchar2(100);
/
drop type T_NUMBER;
--建立一個與T_VarcharArray的id同類型的不定長數組的定義
create or replace type T_NUMBER as table of number(10);
/
create or replace procedure P_VARCHAR2_LST(
i_t_varchar IN t_varchar, --輸入參數為定義的不定長varchar2數組
o_n_ret OUT number --輸出參數,正常結束,則輸出0,否則拋出異常
)
is
begin
FOR i in 1..i_t_varchar.COUNT loop --注意下標從1開始。
insert into T_VarcharArray values (i,i_t_varchar(i));
end loop;
o_n_ret :=0;
exception when others then
raise;
end;
/
create or replace function F_NUMBER_LST(
i_t_number IN t_number --輸入參數為定義的不定長數值數組
)
return number --函數輸出結果
is
begin
FOR i in 1..i_t_number.COUNT loop --注意下標從1開始。
insert into T_VarcharArray values (i_t_number(i),to_char(i));
end loop;
return 0;
exception when others then
raise;
end;
/
Varchar2NumberArray.java
package test.oracle.oj;<br />import java.sql.*;<br />import oracle.jdbc.driver.OracleTypes;<br />import oracle.sql.ARRAY;<br />import oracle.sql.ArrayDescriptor;<br />import test.oracle.conn.OConnection;<br />public class Varchar2NumberArray {<br />// 注意:T_VARCHAR2必須全部大寫<br />private static final String T_VARCHAR = "T_VARCHAR";<br />private static final String T_NUMBER = "T_NUMBER";<br />// 注意:call必須小寫,過程名字必須全部大寫<br />private static final String P_VARCHAR2_LST = "{call P_VARCHAR2_LST(?,?)}";<br />// 注意:call必須小寫,過程名字必須全部大寫,傳回值在java中是第一個<br />private static final String F_NUMBER_LST = "{? = call F_NUMBER_LST(?)}";<br />public static int varchar2LstTest(String[] lst) {<br />int retVal = -1;<br />Connection con = null;<br />CallableStatement cstmt = null;<br />try {<br />con = OConnection.getConn();<br />// 建立一個數組描述符<br />ArrayDescriptor varchar2Desc = ArrayDescriptor.createDescriptor(<br />T_VARCHAR, con);<br />// 將字串數群組轉換為oralce能識別的數組<br />ARRAY vArray = new ARRAY(varchar2Desc, con, lst);<br />cstmt = con.prepareCall(P_VARCHAR2_LST);<br />cstmt.setArray(1, vArray);<br />cstmt.registerOutParameter(2, OracleTypes.INTEGER);<br />cstmt.execute();<br />retVal = cstmt.getInt(2);<br />} catch (Exception ex) {<br />ex.printStackTrace();<br />} finally {<br />// 最好都在finally裡面關閉用到的cs、ps、rs以及con,<br />// 以確保出異常時,該釋放的都被釋放<br />try {<br />if (cstmt != null) {<br />cstmt.close();<br />}<br />if (con != null) {<br />con.close();<br />}<br />} catch (SQLException sqle) {<br />sqle.printStackTrace();<br />}<br />}<br />return retVal;<br />}<br />public static int numberLstTest(int[] lst) {<br />int retVal = -1;<br />Connection con = null;<br />CallableStatement cstmt = null;<br />try {<br />con = OConnection.getConn();<br />// 建立一個數組描述符<br />ArrayDescriptor varchar2Desc = ArrayDescriptor.createDescriptor(<br />T_NUMBER, con);<br />// 將字串數群組轉換為oralce能識別的數組<br />ARRAY vArray = new ARRAY(varchar2Desc, con, lst);<br />cstmt = con.prepareCall(F_NUMBER_LST);<br />// 傳回值在java中是第一個,所以先註冊輸出參數<br />cstmt.registerOutParameter(1, OracleTypes.INTEGER);<br />cstmt.setArray(2, vArray);<br />cstmt.execute();<br />retVal = cstmt.getInt(1);<br />} catch (Exception ex) {<br />ex.printStackTrace();<br />} finally {<br />// 最好都在finally裡面關閉用到的cs、ps、rs以及con,<br />// 以確保出異常時,該釋放的都被釋放<br />try {<br />if (cstmt != null) {<br />cstmt.close();<br />}<br />if (con != null) {<br />con.close();<br />}<br />} catch (SQLException sqle) {<br />sqle.printStackTrace();<br />}<br />}<br />return retVal;<br />}<br />public static void main(String[] args) throws Exception {<br />String[] lst = { "test1", "test2", "test2" };<br />int ret = Varchar2NumberArray.varchar2LstTest(lst);<br />System.out.println("測試字串數組作為參數傳入預存程序,結果:" + ret);<br />int[] lst1 = { 1, 2, 3 };<br />ret = Varchar2NumberArray.numberLstTest(lst1);<br />System.out.println("測試整型數組作為參數傳入預存程序,結果:" + ret);<br />}<br />}<br />
第一篇貌似就這麼結束了,這裡講的只是如何把String數組、int數組傳入oracle並使用,下一節講如何傳出。
喜歡的朋友關注下,記得幫頂噢,合夥哈。