Java代碼調用Oracle的存儲過程,存儲函數和包


 Java代碼調用存儲過程和存儲函數要使用CallableStatement接口

查看API文檔:

 

上代碼:

java代碼調用如下的存儲過程和函數:

查詢某個員工的姓名  月薪 職位

1 create or replace procedure queryEmpinfo(eno in number,
2                                          pename out varchar2,
3                                          psal   out number,
4                                          pjob   out varchar2)
5 as
6 begin
7   select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
8 end;

 

 

 1 --查詢某個員工的年收入
 2 create or replace function queryEmpIncome(eno in number)
 3 return number
 4 as
 5    psal emp.sal%type;
 6    pcomm emp.comm%type;
 7 begin
 8    select sal,comm into psal,pcomm from emp where empno=eno;
 9 
10    --返回年收入
11    return psal*12+nvl(pcomm,0);
12 
13 end;

 

 

 1 --在out參數中使用光標
 2 查詢某個部門中所有員工的所有信息
 3 
 4 
 5 包頭
 6 CREATE OR REPLACE PACKAGE MYPACKAGE AS 
 7 
 8   type empcursor is ref cursor;
 9   procedure queryEmpList(dno in number,empList out empcursor);
10 
11 END MYPACKAGE;
12 
13 
14 包體
15 CREATE OR REPLACE
16 PACKAGE BODY MYPACKAGE AS
17 
18   procedure queryEmpList(dno in number,empList out empcursor) AS
19   BEGIN
20     open empList for select * from emp where deptno=dno;
21   END queryEmpList;
22 
23 END MYPACKAGE;

 

 

  1 import java.sql.CallableStatement;
  2 import java.sql.Connection;
  3 import java.sql.ResultSet;
  4 import java.sql.SQLException;
  5 
  6 import oracle.jdbc.driver.OracleCallableStatement;
  7 import oracle.jdbc.driver.OracleTypes;
  8 
  9 import org.junit.Test;
 10 
 11 public class TestOracle {
 12     
 13     /*
 14      * CallableStatement 接口
 15      *     調用存儲函數,等號左邊有一個返回值
 16      *    {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
 17      *  調用存儲過程. 沒有返回值 
 18              {call <procedure-name>[(<arg1>,<arg2>, ...)]}
 19 
 20      * 
 21      */
 22     
 23     /*存儲過程 查詢某個員工的姓名  月薪 職位
 24      * create or replace procedure queryEmpinfo(eno in number,
 25                                              pename out varchar2,
 26                                              psal   out number,
 27                                              pjob   out varchar2)
 28      */    
 29     
 30     @Test
 31     public void testProcedure(){
 32         //{call <procedure-name>[(<arg1>,<arg2>,...)]}
 33         String sql = "{call queryEmpinfo(?,?,?,?)}";//4個問號中,第一個是輸入參數,其余是輸出參數
 34         Connection conn = null;
 35         //要用CallableStatement這個接口,用於執行 SQL 存儲過程的接口
 36         CallableStatement call = null;
 37         
 38         try {
 39             conn = JDBCUtils.getConnection();
 40             call = conn.prepareCall(sql);
 41             //對於in參數,需要賦值
 42             call.setInt(1,7839);
 43             //對於out參數,需要聲明
 44             call.registerOutParameter(2, OracleTypes.VARCHAR);//第二個是字符串
 45             call.registerOutParameter(3, OracleTypes.NUMBER);//第三個是數字
 46             call.registerOutParameter(4, OracleTypes.VARCHAR);//第四個是字符串
 47             
 48             call.execute();
 49             //取出結果
 50             String name = call.getString(2);
 51             double sal = call.getDouble(3);
 52             String job = call.getString(4);
 53             System.out.println(name+"\t"+sal+"\t"+job+"\t");
 54         } catch (SQLException e) {
 55             e.printStackTrace();
 56         }finally{
 57             JDBCUtils.release(conn, call, null);//沒有最后一個參數就傳入null
 58         }
 59     }
 60 
 61     /*存儲函數  查詢某個員工的姓名,月薪和職位
 62      * create or replace function queryEmpIncome(eno in number)
 63         return number
 64      */    
 65     @Test
 66     public void testFunction(){
 67         //{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
 68         //第一個問號是函數的返回值,第二個問號是輸入參數.  返回值的作用和輸出參數是一樣的.
 69         String sql = "{?=call QUERYEMPINCOME(?)}";//這個call后面的存儲過程名或者是存儲函數名大寫或者是小寫是沒有要求的.
 70         Connection conn = null;
 71         //要用CallableStatement這個接口,用於執行 SQL 存儲過程的接口
 72         CallableStatement call = null;
 73         
 74         try {
 75             conn = JDBCUtils.getConnection();
 76             call = conn.prepareCall(sql);
 77             
 78             //對於in參數,賦值
 79             call.setInt(2,7839);
 80             
 81             //對於out參數,申明
 82             call.registerOutParameter(1, OracleTypes.NUMBER);
 83             call.execute();
 84             //取出結果
 85             //取出結果
 86             double income = call.getDouble(1);
 87             System.out.println(income);
 88         } catch (SQLException e) {
 89             e.printStackTrace();
 90         }finally{
 91             JDBCUtils.release(conn, call, null);//沒有最后一個參數就傳入null
 92         }
 93         
 94         
 95     }
 96     
 97     /*
 98         查詢某個部門中所有員工的所有信息
 99         包頭
100         CREATE OR REPLACE PACKAGE MYPACKAGE AS 
101         
102           type empcursor is ref cursor;
103           procedure queryEmpList(dno in number,empList out empcursor);
104         
105         END MYPACKAGE;
106         
107         
108         包體
109         CREATE OR REPLACE
110         PACKAGE BODY MYPACKAGE AS
111         
112           procedure queryEmpList(dno in number,empList out empcursor) AS
113           BEGIN
114             open empList for select * from emp where deptno=dno;
115           END queryEmpList;
116         
117         END MYPACKAGE;    
118      */
119     @Test
120     public void testCursor(){
121         //{call <procedure-name>[(<arg1>,<arg2>, ...)]}
122         String sql = "{call MYPACKAGE.queryEmpList(?,?)}";
123         
124         Connection conn = null;
125         CallableStatement call = null;
126         //有游標,就有結果集
127         ResultSet rest = null;
128         try {
129             conn = JDBCUtils.getConnection();
130             call = conn.prepareCall(sql);
131             
132             //對於in參數,賦值
133             call.setInt(1, 20);
134             
135             //對於out參數,申明
136             call.registerOutParameter(2, OracleTypes.CURSOR);
137             call.execute();        
138             //取出集合
139             //這個地方要強轉!!!OracleCallableStatement是抽象類,繼承了CallableStatement
140             //不強轉沒有getCursor()方法...
141             rest = ((OracleCallableStatement)call).getCursor(2);
142             while(rest.next()){
143                 String name = rest.getString("ename");
144                 double sal = rest.getDouble("sal");
145                 System.out.println(name+"\t"+sal);
146             }
147         }catch (Exception e) {
148             e.printStackTrace();
149         }finally{
150             JDBCUtils.release(conn, call, rest);//上面打開了光標,再這個地方關閉結果集rest,也就關閉了光標
151         }
152     }
153 }

 

關於Oracle中的包對象:

之前的存儲函數中查詢的是某一個員工的信息:

1 create or replace procedure queryEmpinfo(eno in number,
2                                          pename out varchar2,
3                                          psal   out number,
4                                          pjob   out varchar2)
5 as
6 begin
7   select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
8 end;

但是①如果要查詢一個員工的所有信息,而這個員工的信息對應的有幾百列

在存儲函數中括號的函數要把這幾百列都聲明出來?

②如果要查詢某個部門中所有員工的所有信息...這個信息對應的是一個集合.

第二個問題解決了第一個問題也就解決了.

怎么在存儲過程或者存儲函數中返回一個集合.

學到現在有多少種方式可以代表一個集合?

第一個是表,第二個是select語句也可以.第三個是光標.

在out參數中使用光標.但是有一個要求,必須要聲明一個包,包分為包頭和包體.也是數據庫的對象.跟表,視圖,等是一樣的是數據庫的對象.

包頭只負責聲明,包體只負責實現.

 1 --在out參數中使用光標
 2 查詢某個部門中所有員工的所有信息
 3 
 4 
 5 包頭
 6 CREATE OR REPLACE PACKAGE MYPACKAGE AS 
 7 
 8   type empcursor is ref cursor;
 9   procedure queryEmpList(dno in number,empList out empcursor);
10 
11 END MYPACKAGE;
12 
13 
14 包體
15 CREATE OR REPLACE
16 PACKAGE BODY MYPACKAGE AS
17 
18   procedure queryEmpList(dno in number,empList out empcursor) AS
19   BEGIN
20     open empList for select * from emp where deptno=dno;
21   END queryEmpList;
22 
23 END MYPACKAGE;

 

分析圖:

參看包:

包無法在plsqldeveloper和sqldeveloper等工具中右鍵運行....必須通過java代碼應用程序來調用執行(代碼在上面)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM