在大型數據庫系統中,有兩個很重要做用的功能,那就是存儲過程和觸發器。在數據庫系統中不管是存儲過程仍是觸發器,都是經過SQL 語句和控制流程語句的集合來完成的。相對來講,數據庫系統中的觸發器也是一種存儲過程。存儲過程在數據庫中運算時自動生成各類執行方式,所以,大大提升了對其運行時的執行速度。在大型數據庫系統如Oracle、SQL Server中都不只提供了用戶自定義存儲過程的功能,同時也提供了許多可做爲工具進行調用的系統自帶存儲過程。 所謂存儲過程(Stored Procedure),就是一組用於完成特定數據庫功能的SQL 語句集,該SQL語句集通過編譯後存儲在數據庫系統中。在使用時候,用戶經過指定已經定義的存儲過程名字並給出相應的存儲過程參數來調用並執行它,從而完成一個或一系列的數據庫操做。 因爲J2EE體系通常創建大型的企業級應用系統,而通常都配備大型數據庫系統如Oracle或者SQL Server,在本文《JAVA與Oracle存儲過程》中將介紹JAVA跟Oracle存儲過程之間的相互應用跟相互間的各類調用。 1、JAVA調用Oracle存儲過程 JAVA跟Oracle之間最經常使用的是JAVA調用Oracle的存儲過程,如下簡要說明下JAVA如何對Oracle存儲過程進行調用。 Ⅰ、不帶輸出參數狀況 過程名稱爲pro1,參數個數1個,數據類型爲整形數據 import java.sql. * ; public class ProcedureNoArgs { public static void main(String args[]) throws Exception { // 加載Oracle驅動 DriverManager.registerDriver( new oracle.jdbc.driver.OracleDriver()); // 得到Oracle數據庫鏈接 Connection conn = DriverManager.getConnection( " jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd " ); // 建立存儲過程的對象 CallableStatement c = conn.divpareCall( " {call pro1(?)} " ); // 給Oracle存儲過程的參數設置值 ,將第一個參數的值設置成188 c.setInt( 1 , 188 ); // 執行Oracle存儲過程 c.execute(); conn.close(); } } Ⅱ、帶輸出參數的狀況 過程名稱爲pro2,參數個數2個,數據類型爲整形數據,返回值爲整形類型 import java.sql.*; public class ProcedureWithArgs { public static void main(String args[]) throws Exception { //加載Oracle驅動 DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); //得到Oracle數據庫鏈接 Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd "); //建立Oracle存儲過程的對象,調用存儲過程 CallableStatement c=conn.divpareCall("{call pro2(?,?)}"); //給Oracle存儲過程的參數設置值 ,將第一個參數的值設置成188 c.setInt(1,188); //註冊存儲過程的第二個參數 c.registerOutParameter(2,java.sql.Types.INTEGER); //執行Oracle存儲過程 c.execute(); //獲得存儲過程的輸出參數值並打印出來 System.out.println (c.getInt(2)); conn.close(); } } Oracle存儲過程包含三部分:過程聲明,執行過程部分,存儲過程異常。 Oracle存儲過程能夠有無參數存儲過程和帶參數存儲過程。 1、無參程序過程語法 1 create or replace procedure NoParPro 2 as ; 3 begin 4 ; 5 exception //存儲過程異常 6 ; 7 end; 8 2、帶參存儲過程實例 1 create or replace procedure queryempname(sfindno emp.empno%type) as 2 sName emp.ename%type; 3 sjob emp.job%type; 4 begin 5 .... 7 exception .... 14 end; 15 3、 帶參數存儲過程含賦值方式 1 create or replace procedure runbyparmeters (isal in emp.sal%type, sname out varchar,sjob in out varchar) 2 as icount number; 3 begin 4 select count(*) into icount from emp where sal>isal and job=sjob; 5 if icount=1 then 6 .... 9 else 10 .... 12 end if; 13 exception 14 when too_many_rows then 15 DBMS_OUTPUT.PUT_LINE('返回值多於1行'); 16 when others then 17 DBMS_OUTPUT.PUT_LINE('在RUNBYPARMETERS過程當中出錯!'); 18 end; 19 4、在Oracle中對存儲過程的調用 過程調用方式一 1 declare 2 realsal emp.sal%type; 3 realname varchar(40); 4 realjob varchar(40); 5 begin //存儲過程調用開始 6 realsal:=1100; 7 realname:=''; 8 realjob:='CLERK'; 9 runbyparmeters(realsal,realname,realjob); --必須按順序 10 DBMS_OUTPUT.PUT_LINE(REALNAME||' '||REALJOB); 11 END; //過程調用結束 12 過程調用方式二 1 declare 2 realsal emp.sal%type; 3 realname varchar(40); 4 realjob varchar(40); 5 begin //過程調用開始 6 realsal:=1100; 7 realname:=''; 8 realjob:='CLERK'; 9 runbyparmeters(sname=>realname,isal=>realsal,sjob=>realjob); --指定值對應變量順序可變 10 DBMS_OUTPUT.PUT_LINE(REALNAME||' '||REALJOB); 11 END; //過程調用結束 12 至此,有關ORACLE的基本存儲過程以及對Oracle存儲過程的調用方式介紹完畢。java
學生在學習jdbc的時候,會問到怎麼調用存儲過程,如今將java調用oracle存儲過程的示例總結以下。(關於調用sqlserver的存儲過程將在下次進行小結請關注)sql
一:無返回值的存儲過程數據庫
存儲過程爲:oracle
? create or replace procedure adddept(deptno number,dname varchar2,loc varchar2)工具
? assqlserver
? begin學習
? insert into dept values(deptno,dname,loc);url
? end;.net
而後呢,在java裏調用時就用下面的代碼:指針
? public class TestProcedure {
? Connection conn=null ;
? CallableStatement cstmt=null ;
? PreparedStatement pstmt=null ;
? String url="jdbc:oracle:thin:@localhost:1521:mydb";
? String driver="oracle.jdbc.driver.OracleDriver";
? String name="";
? public TestProcedure() {
? try {
? Class.forName(driver);
? conn=DriverManager.getConnection(url,"scott","tiger");
? cstmt=conn.prepareCall("{call adddept(?,?,?)}");
? cstmt.setInt(1,13);
? cstmt.setString(2,"間諜部2");
? cstmt.setString(3,"ningbo2");
cstmt.executeUpdate();
?
? System.out.println("success");
? }
? catch (Exception e){e.printStackTrace();}
? finally{
? cstmt.close();
? conn.close();
? }
? }
? }
dept表爲oracle數據庫方案scott中的一個表
二:有返回值的存儲過程(非列表)
存儲過程爲:
CREATE OR REPLACE PROCEDURE TESTB(PARA1 IN VARCHAR2,PARA2 OUT VARCHAR2) AS
BEGIN
SELECT INTO PARA2 FROM TESTTB WHERE I_ID= PARA1;
END TESTB;
在java裏調用時就用下面的代碼:
package com.hyq.src;
public class TestProcedureTWO {
public TestProcedureTWO() {
}
public static void main(String[] args ){
String driver = "oracle.jdbc.driver.OracleDriver";
String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl, " hyq ", " hyq ");
CallableStatement proc = null;
proc = conn.prepareCall("{ call HYQ.TESTB(?,?) }");
proc.setString(1, "100");
proc.registerOutParameter(2, Types.VARCHAR);
proc.execute();
String testPrint = proc.getString(2);
System.out.println("=testPrint=is="+testPrint);
}
catch (SQLException ex2) {
ex2.printStackTrace();
}
catch (Exception ex2) {
ex2.printStackTrace();
}
finally{
try {
if(rs != null){
rs.close();
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
catch (SQLException ex1) {
}
}
}
}
}
注意,這裏的proc.getString(2)中的數值2並不是任意的,而是和存儲過程當中的out列對應的,若是out是在第一個位置,那就是proc.getString(1),若是是第三個位置,就是proc.getString(3),固然也能夠同時有多個返回值,那就是再多加幾個out參數了。
三:返回列表
因爲oracle存儲過程沒有返回值,它的全部返回值都是經過out參數來替代的,列表一樣也不例外,但因爲是集合,因此不能用通常的參數,必需要用pagkage了.因此要分兩部分,
1, 建一個程序包。以下:
CREATE OR REPLACE PACKAGE TESTPACKAGE AS
TYPE Test_CURSOR IS REF CURSOR;
end TESTPACKAGE;
2,創建存儲過程,存儲過程爲:
CREATE OR REPLACE PROCEDURE TESTC(p_CURSOR out TESTPACKAGE.Test_CURSOR) IS
BEGIN
OPEN p_CURSOR FOR SELECT * FROM HYQ.TESTTB;
END TESTC;
能夠看到,它是把遊標(能夠理解爲一個指針),做爲一個out 參數來返回值的。
在java裏調用時就用下面的代碼:
package com.hyq.src;
import java.sql.*;
import java.io.OutputStream;
import java.io.Writer;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import oracle.jdbc.driver.*;
public class TestProcedureTHREE {
public TestProcedureTHREE() {
}
public static void main(String[] args ){
String driver = "oracle.jdbc.driver.OracleDriver";
String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl, "hyq", "hyq");
CallableStatement proc = null;
proc = conn.prepareCall("{ call hyq.testc(?) }");
proc.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);
proc.execute();
rs = (ResultSet)proc.getObject(1);
while(rs.next())
{
System.out.println("<tr><td>" + rs.getString(1) + "</td><td>"+rs.getString(2)+"</td></tr>");
}
}
catch (SQLException ex2) {
ex2.printStackTrace();
}
catch (Exception ex2) {
ex2.printStackTrace();
}
finally{
try {
if(rs != null){
rs.close();
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
catch (SQLException ex1) {
}
}
}
}