Oracle數據庫——存儲過程和自定義函數

一、存儲過程和存儲函數

指存儲在數據庫中供所有用戶程序調用的子程序叫存儲過程/存儲函數。

存儲過程和存儲函數的相同點:完成特定功能的程序
存儲過程和存儲函數的區別:是否用return語句返回值

二、創建和使用存儲過程

CREATE PROCEDURE命令建立存儲過程和存儲函數。
語法:
   create [or replace] PROCEDURE 過程名(參數列表) 
   AS
   PLSQL子程序體;

1、第一個存儲過程

打印:Hello World

--第一個存儲過程:打印Hello World
/*
調用存儲過程:
1.exec sayhelloworld() ;
2.begin
	sayhelloworld() ;
	sayhelloworld() ;
  end;
*/
create or replace procedure sayhelloworld
as
--說明部分
begin
	dbms_output.put_line('Hello World');
end;
/

在這裏插入圖片描述
在這裏插入圖片描述

2、調用存儲過程

使用exec語句

使用PL/SQL程序

3、帶參數存儲過程

舉例:爲指定的員工,漲100塊錢的工資;並且打印漲之前和漲之後的薪水。

--創建一個帶參數的存儲過程
--給指定的員工漲100塊錢的工資,並且打印漲前和漲後的薪水
create or replace procedure raisesalary (eno in number)
as
psal emp.sal%type;
begin
	--得到員工漲前的薪水
	select sal into psal from emp where empno = eno;
	--給該員工漲100
	update emp set sal = sal + 100 where empno = eno;
	--打印
	dbms_ output.put_ line('漲前: '||psal||' 漲後: '||(psal + 100));
end;
/

在這裏插入圖片描述

--調用存儲過程
begin
	raisesalary( 7839) ;
	raisesalary( 7566) ;
	commit;
end;
/

在這裏插入圖片描述

4、如何調試存儲過程

被阻斷:
在這裏插入圖片描述
授權:
在這裏插入圖片描述

BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE
(
host => '192.168.128.1', 
lower_port => null,
upper_port => null,
ace => xs$ace_type(privilege_list => xs$name_list('HYHCJ'),
principal_name => 'c##scott',
principal_type => xs_acl.ptype_db)
);
END;

三、存儲函數

  • 函數(Function)爲一命名的存儲程序,可帶參數,並返回一計算機值。

  • 函數和過程的結構類似,但必須有一return子句,用於返回函數值。

1、創建存儲函數的語法

create [or replace] FUNCTION 函數名(參數列表)
return 函數值類型
AS
PLSQL子程序體;

2、存儲函數舉例

查詢某個員工的年收入

--存儲函數:查詢某個員工的年收入
create or replace function query empincome (eno in number)
return number
as
	--定義變量保存員工的薪水和獎金
	psal emp.sal%type;
	pcomm emp.comm%type;
begin
	--得到該員工的月薪和獎金
	select sal, comm into psal, pcomm from emp where empno = eno;
	--直接返回年收入
	return psal*12+nvl(pcomm,0);
end;
/

在這裏插入圖片描述

3、in 和 out參數

一般來講,存儲過程和存儲函數的區別在於存儲函數可以有一個返回值;而存儲過程沒有返回值。

過程和函數都可以通過out指定一個或多個輸出參數。我們可以利用out參數,在過程和函數中實現返回多個值。

  • 存儲過程和存儲函數都可以有out參數
  • 存儲過程和存儲函數都可以有多個out參數
  • 存儲過程可以通過out參數來實現返回值

四、什麼時候用存儲過程/存儲函數?

  • 原則:
    如果只有一個返回值,用存儲函數;否則,就用存儲過程。
--out函數: 查詢某個員工姓名月薪和職位
create or replace procedure queryempinform(eno in number,
											pename out varchar2,
											psal out number ,
											empjob out varchar2)
as
begin
	--得到該員工的姓名月薪和職位
	select ename, sal, empjob into pename, psal, emppjob from emp where empno = eno;
end;
/

在這裏插入圖片描述

1、在應用程序中訪問存儲過程和存儲函數

  • 訪問存儲過程

  • 訪問存儲函數

參考:https://blog.csdn.net/hyh17808770899/article/details/106872076

2、在out參數中使用光標

  • 申明包結構
  • 包頭
  • 包體

案例:查詢某個部門中所有員工的所有信息

包頭:

create or replace package mypackage as
	type empcursor is ref cursor;
	procedure queryEmpList (dno in number, empList out empcursor);
end mypackage;

在這裏插入圖片描述
包體:
包體需要實現包頭中聲明的所有方法

create or replace package body mypackage as
	procedure queryEmpList(dno in number, empList out empcursor) as
	begin
		open empList for select * from emp where deptno = dno;
	end queryEmpList;
end mypackage;

在這裏插入圖片描述

3、在應用中訪問包中的存儲過程

注意:需要帶上包名

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