【Oracle基礎】存儲過程和存儲函數

一、基礎介紹

  • 存儲過程和函數也是數據庫對象,是存儲在數據庫中的被命名的PLSQL塊,供所有用戶程序調用完成特定功能的子程序。
  • 存儲過程類似java中的void方法,主要用途是功能的處理,存儲該函數類似非void方法,需要return返回值。

二、存儲過程

(一) 創建和調用

語法

CREATE [OR REPLACE] PROCEDURE 過程名
[(參數名1  IN|OUT|IN OUT 參數值類型 [DEFAULT 默認值]),
(參數名2  IN|OUT|IN OUT 參數值類型[DEFAULT 默認值])...]
AS|IS
	[變量名 變量類型[:=初始值];    --聲明變量部分 ]
BEGIN
	執行部分;
[EXCEPTION
	異常錯誤處理部分;]
END;

1.無參的存儲過程

1)創建

--創建存儲過程(無參)
CREATE OR REPLACE 
PROCEDURE first_proc2 is--
BEGIN
	DBMS_OUTPUT.PUT_LINE('我是過程2');--打印內容
	DBMS_OUTPUT.PUT_LINE('hello everyone!');
END;

2)調用

BEGIN
	first_proc2;
end;

2.帶輸入參數的存儲過程in

1)創建

create or replace procedure proc_inparams 
(v_empno in EMPNEW.EMPNO%TYPE)--名稱是v_empno的In類型的參數,TYPE與emp_1表的empno字段相同
IS
begin
	--根據員工號刪除指定員工信息
	delete from EMPNEW where empno=v_empno;--一般不用在程序中commit和rollback
	--判斷是否成功
	if SQL%NOTFOUND then
		-- -20000~20999之間
		RAISE_APPLICATION_ERROR(-20008,'指定刪除的員工不存在');--內置的存儲過程,用於在子程序中指定錯誤的自定義信息,錯誤號和錯誤提示內容可以自定義
	ELSE
		DBMS_OUTPUT.PUT_LINE('刪除成功');
	END IF;

end;

2)調用

BEGIN
	PROC_INPARAMS(1234);--調用時傳參
end;
DECLARE
	dpn number:=1234;
BEGIN
	PROC_INPARAMS(dpn);
end;

3.帶輸出過程的存儲過程out

1)創建

create or replace procedure proc_outparams
(v_deptno in number,v_avgsal out number,v_cnt out number)
AS
BEGIN
	select avg(sal),count(*) into v_avgsal,v_cnt --參數變量賦值into
	from EMP
	where deptno=v_deptno;
EXCEPTION
	when NO_DATA_FOUND THEN
		DBMS_OUTPUT.put_line('無此部門');
	when others THEN
		DBMS_OUTPUT.put_line(SQLERRM);
END;

2)調用

DECLARE
	v_avgsalary number;--聲明兩個變量用於接收out參數
	v_count number;
BEGIN
	PROC_OUTPARAMS(10,v_avgsalary,v_count);--位置傳值,聲明的變量按照順序對應接收out參數
	DBMS_OUTPUT.put_line('平均工資:'||v_avgsalary);
	DBMS_OUTPUT.put_line('總人數:'||v_count);
end;

4.帶輸入輸出過程的存儲過程in out

1)創建

create or replace procedure proc_inoutparams
(v_num1 in out number,v_num2 in out number)
as
	v_temp number:=0;--聲明一個叫v_temp的變量,type是NUMBER,賦值0
BEGIN
	--交換兩個數
	v_temp:=v_num1;
	v_num1:=v_num2;
	v_num2:=v_temp;

end;

2)調用

DECLARE
	v_n1 number:=5;--聲明兩個變量用於接收參數
	v_n2 number:=8;
BEGIN
	PROC_INOUTPARAMS(v_n1,v_n2);--聲明的變量按照順序對應接收in out參數
	DBMS_OUTPUT.put_line('v_n1:'||v_n1);
	DBMS_OUTPUT.put_line('v_n2:'||v_n2);
end;

(二) 刪除

drop procedure "first_proc";--過程名區分是否有引號

三、存儲函數

(一) 創建和調用

語法

CREATE [OR REPLACE] FUNCTION 函數名
[(參數名1  IN|OUT|IN OUT 參數值類型 [DEFAULT 默認值]),
(參數名2  IN|OUT|IN OUT 參數值類型 [DEFAULT 默認值])...]
RETURN 返回值類型--比過程多的部分
AS|IS
	[變量名 變量類型[:=初始值];    --聲明變量部分 ]
BEGIN
	執行部分;
[EXCEPTION
	異常錯誤處理部分;]
END;

1.無參的存儲函數

1)創建

CREATE OR REPLACE function "first_func2" 
return VARCHAR2
iS
BEGIN
	DBMS_OUTPUT.PUT_LINE('我是函數2');
	return 'hello,everyone';--對應之前的類型
END;

2)調用

BEGIN
	dbms_output.put_line(first_func2);
end;

2.帶輸入參數的存儲函數in

1)創建

create or replace function func_inparams
(v_deptno in number)
return NUMBER
is
	v_sumsal number;--聲明變量
BEGIN
	--根據部門編號返回部門總工資
	select sum(sal) into v_sumsal from emp where DEPTNO=v_deptno;--變量賦值
	return v_sumsal;--返回變量
EXCEPTION
	when no_data_found THEN
		dbms_output.put_line('無此部門');
	when others THEN
		DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;

2)調用

BEGIN
	dbms_output.put_line('部門工資總和:'||FUNC_INPARAMS(10));
end;

3.帶輸出過程的存儲函數out

1)創建

create or replace function func_outparams
(v_empno in EMP.EMPNO%type, v_name out EMP.ENAME%type,v_sal out EMP.SAL%type )
return number
AS
	v_yasal number;
BEGIN
	--根據員工號輸出員工姓名和工資,並返回員工的年收入
	select ename,sal,(sal+nvl(comm,0))*12 into v_name,v_sal,v_yasal
	from EMP
	where empno=v_empno;
	return v_yasal;
EXCEPTION
	when no_data_found THEN
		dbms_output.put_line('無此員工');
	when others THEN
		DBMS_OUTPUT.PUT_LINE(SQLERRM);	
END;

2)調用

DECLARE
	v_name EMP.ENAME%type;--聲明兩個變量用於接收out參數
	v_sal EMP.SAL%type;
	v_yasal number;
BEGIN
	v_yasal:=FUNC_OUTPARAMS(7369,v_name,v_sal);
	dbms_output.put_line('姓名'||v_name||'的工資是'||v_sal||',年總收入是:'||v_yasal);
end;

4.帶輸入輸出過程的存儲函數in out

1)創建

create or replace function func_inoutparams
(n1 in out number,n2 in out number)
return NUMBER
AS
BEGIN
	n1:=n1*n1;
	n2:=n2*n2;
	return n1+n2;
end;

2)調用

DECLARE
	v_n1 number :=5;
	v_n2 number :=8;
BEGIN
	dbms_output.put_line(v_n1||'和'||v_n2||'的和是:'||FUNC_INOUTPARAMS(v_n1, v_n2));--此時v_n1和v_n2已經參與函數計算
end;

(二) 刪除

drop function "first_func";

四、使用DEFAULT默認值

1.單個參數

--------------------------------求部門的年收入----------------------
--創建
CREATE OR REPLACE 
function func_defa
(v_deptno in number DEFAULT 10)
return NUMBER
AS
	v_deptysal number;
BEGIN
	select sum(sal+nvl(comm,0))*12 into v_deptysal
	from emp where deptno=v_deptno;
	return v_deptysal;
EXCEPTION
	when NO_DATA_FOUND THEN
		DBMS_OUTPUT.put_line('沒有此部門');
	when others THEN
		DBMS_OUTPUT.put_line(SQLERRM);
end;


--調用
BEGIN
	dbms_output.put_line('部門年收入總和:'||FUNC_DEFA);--使用默認值,不用傳參
	dbms_output.put_line('部門年收入總和:'||FUNC_DEFA(20));--不用默認值,需要傳參
end;

2.多個參數

---------------------------求部門的年收入---------------------
--創建
CREATE OR REPLACE 
function func_defa2
(v_deptno in number DEFAULT 10,v_test in number)
return NUMBER
AS
	v_deptysal number;
BEGIN
	select sum(sal+nvl(comm,0))*12 into v_deptysal
	from emp where deptno=v_deptno;
	DBMS_OUTPUT.put_line('測試:'||v_test);
	return v_deptysal;
EXCEPTION
	when NO_DATA_FOUND THEN
		DBMS_OUTPUT.put_line('沒有此部門');
	when others THEN
		DBMS_OUTPUT.put_line(SQLERRM);
end;

--調用
BEGIN
	--dbms_output.put_line('部門年收入總和:'||FUNC_DEFA2(,888));--第一個參數省略時,位置傳值,報錯,不能這樣傳
	dbms_output.put_line('部門年收入總和:'||FUNC_DEFA2(v_test=>888));--名稱傳值,關聯符號=>
end;

五、比較

1.關鍵字

創建過程:procedure
創建函數:function

2.調用方式

存儲過程使用獨立的調用語句

begin
	proc1
end;

存儲函數以表達式方式調用

declare
	v_result NUMBER;
begin
	v_result:=func1;
end;

4.return返回值

存儲函數通過return語句返回函數值,存儲過程則沒有

5.用途

存儲過程的目的是完成一系列的數據處理;存儲函數的目的是獲得函數返回值。

6.參數

過程和函數都可以有一個或多個out輸出函數。
存儲過程沒有return語句,但是可以通過out參數來實現返回值。
一般原則,如果只有一個返回值,用存儲函數處理

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