Oracle系列:(29)存儲過程和存儲函數


一、存儲過程【procedure】sql


什麼是存儲過程?數據庫

事先運用oracle語法寫好的一段具備業務功能的程序片斷,長期保存在oracle服務器中,供oracle客戶端(例如,sqlplus)和程序語言遠程訪問,相似於Java中的函數。
服務器



爲何要用存儲過程?oracle

    (1)PLSQL每次執行都要總體運行一遍,纔有結果ide

    (2)PLSQL不能將其封裝起來,長期保存在oracle服務器中函數

    (3)PLSQL不能被其它應用程序調用,例如:Javaoop


存儲過程與PLSQL是什麼關係?spa

存儲過程是PLSQL的一個方面的應用,而PLSQL是存儲過程的基礎。orm

即存儲過程須要用到PLSQL。對象


--------------------------------------------------------存儲過程


語法:

create [or replace] procedure 過程名[(參數列表)]  
as
PLSQL程序體;


注意:存儲過程當中有【begin…end;/】,無declare


建立無參存儲過程hello,無返回值,語法:create or replace procedure 過程名 as PLSQL程序

create or replace procedure hello
as
begin
       dbms_output.put_line('這是個人第一個存儲過程'); 
end;
/


刪除存儲過程hello,語法:drop procedure 過程名

drop procedure hello;


調用存儲過程方式一,exec 存儲過程名

exec hello;


調用存儲過程方式二,PLSQL程序

begin
  hello;  
end;
/

wKioL1fVT4DQUYZJAABzyHYtUy4172.jpg


調用存儲過程方式三,Java程序

JDBC中講過一個對象:CallableStatement


建立有參存儲過程raiseSalary(編號),爲7369號員工漲10%的工資,演示in的用法,默認in,大小寫不敏感

-- 定義過程
create or replace procedure raiseSalary(pempno number)
as
begin
  update emp set sal=sal*1.2 where empno=pempno;
end;
/

-- 調用過程
exec raiseSalary(7369);

wKiom1fVUOXQv5CLAAB9nNBe5-A878.jpg


建立有參存儲過程findEmpNameAndSalAndJob(編號),查詢7788號員工的的姓名,職位,月薪,返回多個值,演示out的用法

-- 定義過程
create or replace procedure findEmpNameAndSalAndJob(pempno in number,pename out varchar2,pjob out varchar2,psal out number)
as
begin
  select ename,job,sal into pename,pjob,psal from emp where empno=pempno;
end;
/
-- 調用過程
declare
   pename emp.ename%type;
   pjob emp.job%type;
   psal emp.sal%type;
begin
  findEmpNameAndSalAndJob(7369,pename,pjob,psal);
  dbms_output.put_line('7369號員工的姓名是' || pename ||',職位是' || pjob || ',月薪是' || psal);
end;
/

wKiom1fVWY7Aidi_AADctoOCqio886.jpg


什麼狀況下用exec調用,什麼狀況下用PLSQL調用存儲過程?

exec適合於調用存儲過程無返回值

plsql適合於調用存儲過程有返回值,無論多少個


用存儲過程,寫一個計算我的所得稅的功能

-- 定義存儲過程
create or replace procedure get_rax(sal in number,rax out number)
as
  -- sal表示收入
  -- bal 表示須要交稅的收收入
  bal number;
begin
  bal := sal - 3500;
  if bal <= 1500 then
    rax := bal * 0.03 - 0;
  elsif bal <= 4500 then
    rax := bal * 0.1 - 105;
  elsif bal <=9000 then
    rax := bal * 0.2 - 555;
  elsif bal <=35000 then
    rax := bal * 0.25 - 1005;
  elsif bal <= 55000 then
    rax := bal * 0.3 - 2755;
  elsif bal <=80000 then
    rax := bal * 0.35 - 5505;
  else 
    rax := bal * 0.45 - 13505;
  end if;
end;
/


-- 調用存儲過程
declare
   -- 須要交的稅
   rax number;
begin
   get_rax(&sal,rax);
   dbms_output.put_line('你須要交稅' || rax);     
end;
/

wKioL1fVX6mBSFdJAAC0QtxHYjs076.jpg


二、存儲函數



建立無參存儲函數getName,有返回值,語法:create or replace function 函數名 return 返回類型 as PLSQL程序段

create or replace function get_name return varchar2
as 
begin
       return 'hello 你好';  
end;
/


刪除存儲函數getName,語法:drop function 函數名

drop function get_name;


調用存儲函數方式一,PLSQL程序

declare
  name varchar2(20);
begin
  name := get_name(); 
  dbms_output.put_line(name); 
end;
/


調用存儲函數方式二,Java程序


建立有參存儲函數findEmpIncome(編號),查詢7369號員工的年收入,演示in的用法,默認in

-- 定義存儲函數
create or replace function findEmpIncome(pempno in number) return number
as
       income number; 
begin
  select sal*12+NVL(comm,0) into income from emp where empno=pempno;
  return income;
end;
/
-- 調用存儲函數
declare
   income number;
begin
   income := findEmpIncome(&income);
   dbms_output.put_line('該員工的年收入爲' || income);
end;
/

wKiom1fVY__jL_zbAACZPDIPKxs205.jpg

建立有參存儲函數findEmpNameAndJobAndSal(編號),查詢7788號員工的的姓名(return),職位(out),月薪(out),返回多個值

-- 定義存儲函數
create or replace function findEmpNameAndJobAndSal(pempno in number,pjob out varchar2, psal out number) return varchar2
as
       pename emp.ename%type;
begin
       select ename,job,sal into pename,pjob,psal from emp where empno=pempno;
       return pename;       
end;
/

-- 調用存儲函數
declare
   pename emp.ename%type;
   pjob emp.job%type;
   psal emp.sal%type;
begin
   pename := findEmpNameAndJobAndSal(&empno,pjob,psal);
   dbms_output.put_line('7369號員工的姓名是'|| pename ||',職位是'|| pjob || ',月薪是' || psal);
end;
/


三、存儲過程和存儲函數的適合場景



注意:適合不是強行要使用,只是優先考慮


什麼狀況下【適合使用】存儲過程?什麼狀況下【適合使用】存儲函數?

    【適合使用】存儲過程:無返回值 或 有多個返回值時,適合用過程 

    【適合使用】存儲函數:有且只有一個返回值時,適合用函數

   

什麼狀況【適合使用】過程函數,什麼狀況【適合使用】SQL?

    【適合使用】過程函數:

    》須要長期保存在數據庫中

          》須要被多個用戶重複調用

          》業務邏輯相同,只是參數不同

    》批操做大量數據,例如:批量插入不少數據

    【適合使用】SQL:

    》凡是上述反面,均可使用SQL

    》對錶,視圖,序列,索引,等這些仍是要用SQL 


批量添加操做示例:

-- 定義過程
create or replace procedure batchInsert
as
       i number(4) := 1;
begin
       for i in 1..999
           loop
             insert into emp(empno,ename) values(i,'員工'||i);
           end loop; 
end;
/

-- 調用過程
exec batchInsert;
相關文章
相關標籤/搜索