Oracle—存儲過程(轉)

存儲過程和函數—簡介:

存儲過程和函數也是一種PL/SQL塊,是存入數據庫的PL/SQL塊。但存儲過程和函數不同於已經介紹過的PL/SQL程序,我們通常把PL/SQL程序稱爲無名塊,而存儲過程和函數是以命名的方式存儲於數據庫中的。和PL/SQL程序相比,存儲過程有很多優點,具體歸納如下:

* 存儲過程和函數以命名的數據庫對象形式存儲於數據庫當中。存儲在數據庫中的優點是很明顯的,因爲代碼不保存在本地,用戶可以在任何客戶機上登錄到數據庫,並調用或修改代碼。
* 存儲過程和函數可由數據庫提供安全保證,要想使用存儲過程和函數,需要有存儲過程和函數的所有者的授權,只有被授權的用戶或創建者本身才能執行存儲過程或調用函數。
* 存儲過程和函數的信息是寫入數據字典的,所以存儲過程可以看作是一個公用模塊,用戶編寫的PL/SQL程序或其他存儲過程都可以調用它(但存儲過程和函數不能調用PL/SQL程序)。一個重複使用的功能,可以設計成爲存儲過程,比如:顯示一張工資統計表,可以設計成爲存儲過程;一個經常調用的計算,可以設計成爲存儲函數;根據僱員編號返回僱員的姓名,可以設計成存儲函數。
* 像其他高級語言的過程和函數一樣,可以傳遞參數給存儲過程或函數,參數的傳遞也有多種方式。存儲過程可以有返回值,也可以沒有返回值,存儲過程的返回值必須通過參數帶回;函數有一定的數據類型,像其他的標準函數一樣,我們可以通過對函數名的調用返回函數值。
   存儲過程和函數需要進行編譯,以排除語法錯誤,只有編譯通過才能調用。

一、創建存儲過程

創建存儲過程,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系統權限。該權限可由系統管理員授予。創建一個存儲過程的基本語句如下:

CREATE [OR REPLACE] PROCEDURE 存儲過程名[(參數[IN|OUT|IN OUT] 數據類型...)]
{AS|IS}
[說明部分]
BEGIN
可執行部分
[EXCEPTION
錯誤處理部分]
END [過程名];

其中:
可選關鍵字OR REPLACE 表示如果存儲過程已經存在,則用新的存儲過程覆蓋,通常用於存儲過程的重建。
參數部分用於定義多個參數(如果沒有參數,就可以省略)。參數有三種形式:IN、OUT和IN OUT。如果沒有指明參數的形式,則默認爲IN。

關鍵字AS也可以寫成IS,後跟過程的說明部分,可以在此定義過程的局部變量。

二、刪除存儲過程

一個存儲過程在不需要時可以刪除。刪除存儲過程的人是過程的創建者或者擁有DROP ANY PROCEDURE系統權限的人。刪除存儲過程的語法如下:
DROP PROCEDURE 存儲過程名;

三、執行存儲過程

執行(或調用)存儲過程的人是過程的創建者或是擁有EXECUTE ANY PROCEDURE系統權限的人或是被擁有者授予EXECUTE權限的人。執行的方法如下:

方法1—適用於在SQL*Plus(命令語句)中調用存儲過程:

EXECUTE 模式名.存儲過程名[(參數...)];
方法2—在PL/SQL中調用存儲過程:

BEGIN
模式名.存儲過程名[(參數...)];
END;

或者
call 模式名.存儲過程名[(參數...)] 

注意:存儲過程沒有參數時,exec和begin可以直接跟過程名(可以省略( )),但call則必須帶上( )

傳遞的參數必須與定義的參數類型、個數和順序一致(如果參數定義了默認值,則調用時可以省略參數)。參數可以是變量、常量或表達式。

如果是調用本賬戶下的存儲過程,則模式名可以省略。要調用其他賬戶編寫的存儲過程,則模式名必須要添加。

以下是一個生成和調用簡單存儲過程的訓練。注意要事先授予創建存儲過程的權限。

四、授權其它賬戶使用存儲過程

GRANT EXECUTE ON 存儲過程名[(參數...)] TO 賬戶名

注意:如果驗證存儲過程是不是正確,可以在編輯界面編譯一下。

案例:
案例1:創建基礎存儲過程——統計人數

----創建表
create table test_table
(
 id1   varchar2(12),
 name  varchar2(32)
);

----賦值
insert into test_table(id1,name)
values('1','zhangsan');

insert into test_table(id1,name)
values('2','lisi');

insert into test_table(id1,name)
values('3','wangwu');

insert into test_table(id1,name)
values('4','zhaoliu');

insert into test_table(id1,name)
values('5','laowu');

----創建存儲過程
create or replace procedure test_count
as
v_total number(10); --聲明變量
begin
  select count(*) into v_total from test_table;
  dbms_output.put_line('總人口數:'||v_total);
  end;

----運行存儲過程
 begin
   test_count;
   end;
 
 set serveroutput on;
 EXECUTE test_count;

----刪除存儲過程
drop procedure test_count;

SQL語句執行結果:

命令語句執行結果:

案例2:創建一個帶計算的有參數的存儲過程

----創建存儲過程
create or replace procedure test (     
p1 in out number,p2 in number,r1 out number,r2 out number) as  
begin    
  r1 := p1 + p2;  
  r2 := p1 - p2;   
  p1 := 888;  
end test; 
------調用存儲過程 
   declare   --聲明
      a number(3) := 100;  --“:=”是賦值
      b number(4) := 1000;  
      c number(5) := 100;   
      d number(4) := 100;  
    begin  
      test(a,b,c,d);   --在PL/SQL中可以<span style="color:#ff0000;"><strong>在語句塊中</strong></span>直接引用,但在Sqlplus(或者commend中)需要call或者execute命令  
      dbms_output.put_line('a + b = ' || c);  
      dbms_output.put_line('a - b = ' || d);  
      dbms_output.put_line('但a的值爲:' || a || ', b的值爲:' || b);  
    end;  
----結果
a + b = 1100  
a - b = -900  
但a的值爲:888, b的值爲:1000
--IN 定義一個輸入參數變量,用於傳遞參數給存儲過程
--OUT 定義一個輸出參數變量,用於從存儲過程獲取數據
--IN OUT 定義一個輸入,輸出參數變量,兼有兩者功能

案例3:創建一個使用遊標的存儲過程:

--創建存儲過程
create or replace procedure test_list
as
cursor test_cursor is select t.id1,t.name from test_table t; --使用遊標
begin
   for test_record in test_cursor loop --遍歷遊標,再打印出來
     dbms_output.put_line(test_record.id1||test_record.name);
     end loop;
     test_count; --同時調用另外一個存儲過程
     end;

--結果
1zhangsan
2lisi
3wangwu
4zhaoliu
5laowu
總人口數:5


















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