1. 程式人生 > >PL/SQL學習筆記_03_存儲函數與存儲過程

PL/SQL學習筆記_03_存儲函數與存儲過程

employ span function aps 學習 lsi acl 操作 img

ORACLE 提供可以把 PL/SQL 程序存儲在數據庫中,並可以在任何地方來運行它。這樣就叫存儲過程或函數

存儲函數:有返回值,創建完成後,通過select function() from dual;執行

存儲過程:由於沒有返回值,創建完成後,不能使用select語句,只能使用pl/sql塊執行

一.存儲函數

1.存儲函數語法格式

CREATE [OR REPLACE]  FUNCTION  function_name
    [ (argment [ { IN | IN OUT }       ] Type, 
       argment [ { IN | OUT | IN OUT } 
] Type )] --返回值類型 RETURN return_type IS --PL/SQL塊變量、記錄類型、遊標的聲明(類似於前面的declare的部分) BEGIN --函數體(可以實現增刪改查等操作,返回值需要return) return 返回值; EXCEPTION --異常捕獲 END;

註:. IN 表示傳遞給函數的值在該函數執行中不改變;

OUT表示一個值在函數中進行計算並通過該參數傳遞給調用語句;

IN OUT

表示傳遞給函數的值可以變化並傳遞給調用語句.

若省略標記, 則參數隱含為 IN

【例1】不帶參函數

要求:函數的 helloworld: 返回一個 "helloworld" 的字符串

技術分享
create or replace function hello_func
return varchar2
is
begin
       return helloworld;
end;
View Code

執行函數

技術分享
begin
    dbms_output.put_line(hello_func());
end;
View Code

【例2】帶參函數

要求:返回一個"helloworld: atguigu"的字符串,其中atguigu 由執行函數時輸入。

技術分享
--函數的聲明(有參數的寫在小括號裏)
create or replace function hello_func(v_logo varchar2)
--返回值類型
return varchar2
is 
--PL/SQL塊變量的聲明
begin
--函數體
       return helloworld|| v_logo;
end;
View Code

【例3】

要求:獲取給定部門的工資總和, 要求:部門號定義為參數, 工資總額定義為返回值.

技術分享
create or replace function sum_sal(dept_id number)
       return number
       is
       
       cursor sal_cursor is select salary from employees where department_id = dept_id;
       v_sum_sal number(8) := 0;   
begin
       for c in sal_cursor loop
           v_sum_sal := v_sum_sal + c.salary;
       end loop;       

       --dbms_output.put_line(‘sum salary: ‘ || v_sum_sal);
       return v_sum_sal;
end;
View Code

執行函數

技術分享
begin
    dbms_output.put_line(sum_sal(80));
end;
View Code

2. OUT 型參數

因為函數只能有一個返回值, PL/SQL 程序可以通過 OUT 型的參數實現有多個返回值

【例4】

要求: 定義一個函數: 獲取給定部門的工資總和 和 該部門的員工總數(定義為 OUT 類型的參數). 部門號定義為參數, 工資總額定義為返回值.

技術分享
create or replace function sum_sal(dept_id number, total_count out number)
       return number
       is
       
       cursor sal_cursor is select salary from employees where department_id = dept_id;
       v_sum_sal number(8) := 0;   
begin
       total_count := 0;

       for c in sal_cursor loop
           v_sum_sal := v_sum_sal + c.salary;
           total_count := total_count + 1;
       end loop;       

       --dbms_output.put_line(‘sum salary: ‘ || v_sum_sal);
       return v_sum_sal;
end;   
View Code

執行函數

技術分享
delare 
  v_total number(3) := 0;

begin
    dbms_output.put_line(sum_sal(80, v_total));
    dbms_output.put_line(v_total);
end;
View Code

3.刪除函數

DROP    FUNCTION    [user.]Function_name;

二.存儲過程

1.存儲過程語法格式

CREATE [OR REPLACE]  PROCEDURE  Procedure_name
    [ (argment [ { IN | IN OUT }       ] Type, 
       argment [ { IN | OUT | IN OUT } ] Type )]

IS 
      --PL/SQL塊變量、記錄類型、遊標的聲明(類似於前面的declare的部分)
BEGIN
      --函數體(可以實現增刪改查等操作,返回值需要return)
      
EXCEPTION
      --異常捕獲
END;

【例5】

要求:對給定部門(作為輸入參數)的員工進行加薪操作, 若其到公司的時間在 (? , 95) 期間, 為其加薪 %5

[95 , 98) %3
[98, ?) %1
得到以下返回結果: 為此次加薪公司每月需要額外付出多少成本(定義一個 OUT 型的輸出參數).

技術分享
create or replace procedure add_sal_procedure(dept_id number, temp out number)

is

       cursor sal_cursor is select employee_id id, hire_date hd, salary sal from employees where department_id = dept_id;
       a number(4, 2) := 0;
begin
       temp := 0;       

       for c in sal_cursor loop
           a := 0;    
       
           if c.hd < to_date(1995-1-1, yyyy-mm-dd) then
              a := 0.05;
           elsif c.hd < to_date(1998-1-1, yyyy-mm-dd) then
              a := 0.03;
           else
              a := 0.01;
           end if;
           
           temp := temp + c.sal * a;
           update employees set salary = salary * (1 + a) where employee_id = c.id;
       end loop;       
end;
View Code

2.刪除存儲過程

DROP   PROCEDURE   [user.]Procudure_name;

PL/SQL學習筆記_03_存儲函數與存儲過程