存儲過程和存儲函數

一、存儲過程和存儲函數區別:

1、本質相同,沒有區別

2、函數的存在是讓過程調用,存儲過程內部又是調用存儲函數

3、存儲函數可以在sql語句中直接調用  如 select  函數  from 表名

4、存儲過程能實現的,存儲函數也都可以實現,存儲函數可以實現的,存儲過程也都可以實現

5、存儲過程中可以沒有返回值,也可以有多個,但存儲函數中強制返回一個return

 

二、存儲過程和存儲函數創建

存儲過程和存儲函數創建的語法類似

create [or replace]   中 or replace是一個可選參數,表示 存在同名函數/過程 覆蓋更新,不存在則創建,一般開始創建時不推薦使用,防止將原有的刪除。

過程/函數名後面參數  參數名 in | out 參數類型   in表示輸入,out表是輸出

is ...

begin

...

end;

則和傳統的plsql編程類似,is後 定義參數變量,begin 編寫主流程語句,end表示結束。

/*
  存儲過程
  create [or replace] procedure 存儲過程名(參數1 in | out 參數類型,參數1 in | out 參數類型)
  is 
     定義參數
  begin
    過程...
  end;
*/

/*
  存儲函數
  create [or replace] function 函數名(參數1 in 參數類型,參數1 in 參數類型) return 返回值類型
  is | as
     定義參數
  begin
    存儲函數過程
  end;
    
*/

三、存儲過程和存儲函數的事例

eg 例子:

-- 根據empno求emp年薪 存儲函數
create or replace function fun_getsumsal(vempno in number) return number
is
  vsumsal number;
begin
  select sal*12 + nvl(comm,0) into vsumsal from emp where empno = vempno;
  return vsumsal;
end;

-- plsql編程調用
declare

begin
  dbms_output.put_line(fun_getsumsal(7369));
end;


-- 存儲過程實現年薪
create procedure proc_gettotalsal(vempno in number,totalsal out number)
is

begin
  select sal*12 + nvl(comm,0) into totalsal from emp where empno = vempno;
end;

-- plsql編程調用
declare
  total number;
begin
  proc_gettotalsal(7369,total);
  dbms_output.put_line(total);
end;

四、java代碼調用存儲過程和存儲函數

java調用方法類似,都是先jdbc連接數據庫,通過conn.prepareCall(sql)的這個方法進行存儲過程和存儲函數的調用。

不同的sql書寫方式

存儲過程:String sql = "{call proc_gettotalsal(?,?)}";     {call 存儲過程名(?,?)}        無返回值

存儲函數:String sql = "{ ? = call proc_gettotalsal(?)}";     {? = call 存儲過程名(?)}     有返回值

? 是後續conn.prepareCall(sql);獲取的CallableStatement:statement進行參數設置,輸入可以直接使用set方法,輸出使用statement.registerOutParameter(int num, OracleTypes.NUMBER)方法,第一個參數代碼代碼?的索引,也就是第幾個,第二個參數代碼輸出值得類型。

(1)調用存儲過程

@Test
	public void demo1() throws Exception {
		//註冊驅動
		Class.forName("oracle.jdbc.driver.OracleDriver");
		//獲取連接
		String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
		String username = "jzxy";
		String password = "jzxy";
		Connection conn = DriverManager.getConnection(url, username, password);
		//獲取執行SQL的statement.這是一個固定格式  proc_gettotalsal是一個存儲函數
		String sql = "{call proc_gettotalsal(?,?)}";
		CallableStatement statement = conn.prepareCall(sql);
		// 設置輸入參數
		statement.setInt(1, 7369);
		// 設置輸出參數
		statement.registerOutParameter(2, OracleTypes.NUMBER);
		// 執行
		statement.execute();
		// 獲取輸出值
		int total = statement.getInt(2);
		System.out.println(total);
		// 關閉資源
		statement.close();
		conn.close();
		
	}

(2)調用存儲函數

@Test
	public void demo2() throws Exception {
		//註冊驅動
		Class.forName("oracle.jdbc.driver.OracleDriver");
		//獲取連接
		String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
		String username = "jzxy";
		String password = "jzxy";
		Connection conn = DriverManager.getConnection(url, username, password);
		//獲取執行SQL的statement.這是一個固定格式  proc_gettotalsal是一個存儲函數
		String sql = "{? = call fun_getsumsal(?)}";
		CallableStatement statement = conn.prepareCall(sql);
		// 設置輸出參數
		statement.registerOutParameter(1, OracleTypes.NUMBER);
		// 設置輸入參數
		statement.setInt(2, 7369);
		
		// 執行
		statement.execute();
		// 獲取輸出值
		int total = statement.getInt(1);
		System.out.println(total);
		// 關閉資源
		statement.close();
		conn.close();
		
	}

 

 

 

 

 

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