1. 程式人生 > >oracle儲存過程--在應用程式中訪問儲存過程程式完整舉例

oracle儲存過程--在應用程式中訪問儲存過程程式完整舉例

認識儲存過程和函式

儲存過程和函式也是一種PL/SQL塊,是存入資料庫的PL/SQL塊。但儲存過程和函式不同於已經介紹過的PL/SQL程式,我們通常把PL/SQL程式稱為無名塊,而儲存過程和函式是以命名的方式儲存於資料庫中的。和PL/SQL程式相比,儲存過程有很多優點,具體歸納如下:
* 儲存過程和函式以命名的資料庫物件形式儲存於資料庫當中。儲存在資料庫中的優點是很明顯的,因為程式碼不儲存在本地,使用者可以在任何客戶機上登入到資料庫,並呼叫或修改程式碼。
* 儲存過程和函式可由資料庫提供安全保證,要想使用儲存過程和函式,需要有儲存過程和函式的所有者的授權,只有被授權的使用者或建立者本身才能執行儲存過程或呼叫函式。
* 儲存過程和函式的資訊是寫入資料字典的,所以儲存過程可以看作是一個公用模組,使用者編寫的PL/SQL程式或其他儲存過程都可以呼叫它(但儲存過程和函式不能呼叫PL/SQL程式)。一個重複使用的功能,可以設計成為儲存過程,比如:顯示一張工資統計表,可以設計成為儲存過程;一個經常呼叫的計算,可以設計成為儲存函式;根據僱員編號返回僱員的姓名,可以設計成儲存函式。
* 像其他高階語言的過程和函式一樣,可以傳遞引數給儲存過程或函式,引數的傳遞也有多種方式。儲存過程可以有返回值,也可以沒有返回值,儲存過程的返回值必須通過引數帶回;函式有一定的資料型別,像其他的標準函式一樣,我們可以通過對函式名的呼叫返回函式值。
   儲存過程和函式需要進行編譯,以排除語法錯誤,只有編譯通過才能呼叫。

首先得有表盒資料,那麼第一步就是建立表盒插入資料:

SQL> create table emp
  2  (empno number,
  3  ename varchar2(10),
  4  sal number,
  5  job varchar2(100)
  6  );
 
Table created
 
SQL> insert into emp values(1,'王一',10000,'軟體工程師');
 
1 row inserted
 
SQL> insert into emp values(2,'王二',8000,'攝影師');
 
1 row inserted
 
SQL> select * from emp;
 
     EMPNO ENAME             SAL JOB
---------- ---------- ---------- --------------------------------------------------------------------------------
         1 王一          10000 軟體工程師
         2 王二           8000 攝影師
 
SQL> 
現在叫我們查詢某個員工姓名,月薪和職位,那麼我們建立一個儲存過程如下:
--out引數:查詢某個員工姓名,月薪和職位
/*
  思考:
  1、查詢某個員工的所有資訊-->out引數太多?
  2、查詢某個部門中所有員工的所有資訊-->out中返回集合?
*/
--刪除儲存過程

create or replace procedure queryempincome1(eno in number,
                                           pename out varchar2,
                                           psal out number,
                                           pjob out varchar2)
as                                          
begin
   --得到該員工的姓名、月薪和職位 
   select ename,sal,job into pename,psal,pjob from emp where empno=eno;                                    
end;
/                           

然後我們在eclipse裡面編寫Java程式碼連結oracle資料庫和訪問儲存過程,在控制檯輸出指定id的使用者的基本資訊:
package cn.edu.jdbc;

import java.sql.CallableStatement;
import java.sql.Connection;

import oracle.jdbc.OracleTypes;

import org.junit.Test;
/**
 * create or replace procedure queryempinform(eno in number,
                                           pename out varchar2,
                                           psal out number,
                                           pjob out varchar2)
 * @author wf
 *
 */
public class TestProcedure {
	@Test
	public void testProcedure(){
		//{call <procedure-name[(<arg1>,<arg2>,<arh3>...)]>}
		String sql = "{call queryempincome1(?,?,?,?)}";
		
		Connection connection = null;
		CallableStatement call = null;
		try {
			//得到一個連線
			connection = JDBCUtils.getConnection();
			//通過連線建立輸出statement
			call = connection.prepareCall(sql);
			
			//對於in(輸入)引數,要賦值
			call.setInt(1, 2);//為第一個儲存過程的引數賦值為1表示查詢編號為1的員工資訊
			
			//對於out(輸出),需要申明
//			call.registerOutParameter(2, sqlType);
			call.registerOutParameter(2, OracleTypes.VARCHAR);//指定oracle的輸出引數型別
			call.registerOutParameter(3, OracleTypes.NUMBER);
			call.registerOutParameter(4, OracleTypes.VARCHAR);
			
			//執行呼叫
			call.execute();
			
			//取出結果
			String name = call.getString(2);
			Double sal = call.getDouble(3);
			String job = call.getString(4);
			System.out.println("姓名:"+name+"\t"+"薪水:"+sal+"\t"+"工作:"+job);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}