一、存儲過程和存儲函數
指存儲在數據庫中供所有用戶程序調用的子程序叫存儲過程/存儲函數。
存儲過程和存儲函數的相同點:完成特定功能的程序
存儲過程和存儲函數的區別:是否用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、在應用中訪問包中的存儲過程
注意:需要帶上包名