在本章中,咱們將討論PL/SQL中的存儲過程。 子程序是執行特定任務的程序單元/模塊。 這些子程序組合起來造成更大的程序。這種作法被稱爲「模塊化設計」。 子程序能夠被稱爲調用程序的另外一個子程序或程序調用。sql
能夠在如下幾個地方中建立一個子程序 -shell
在模式(schema)級別中,子程序是一個獨立的子程序。它是使用CREATE PROCEDURE
或CREATE FUNCTION
語句建立的。它存儲在數據庫中,能夠使用DROP PROCEDURE
或DROP FUNCTION
語句進行刪除。數據庫
在包中建立的子程序是打包的子程序。它存儲在數據庫中,只有當使用DROP PACKAGE
語句刪除程序包時,才能將其刪除。咱們將在「PL/SQL程序包」一章中討論程序包的應用。模塊化
PL/SQL子程序被命名爲能夠使用一組參數調用的PL/SQL塊。 PL/SQL提供兩種子程序 -函數
本章將主要介紹PL/SQL中的存儲過程。在下一章介紹討論PL/SQL函數。設計
每一個PL/SQL子程序都有一個名稱,也可能有一個參數列表。 像匿名PL/SQL塊同樣,命名塊也將具備如下三個部分 -code
編號 | 部分 | 描述 |
---|---|---|
1 | 聲明部分 | 這是一個可選的部分。可是,子程序的聲明部分不以DECLARE 關鍵字開頭。 它包含類型,遊標,常量,變量,異常和嵌套子程序的聲明。這些項是本子程序,當子程序完成執行時,它們將不復存在。 |
2 | 可執行部分 | 這是一個強制性部分(必須有),幷包含執行指定操做的語句。 |
3 | 異常處理 | 這是一個可選的部分。它包含處理運行時錯誤的代碼。 |
可以使用CREATE OR REPLACE PROCEDURE
語句來建立一個存儲過程。 CREATE OR REPLACE PROCEDURE
語句的簡化語法以下:字符串
CREATE [OR REPLACE] PROCEDURE procedure_name [(parameter_name [IN | OUT | IN OUT] type [, ...])] {IS | AS} BEGIN < procedure_body > END procedure_name;
其中,table
IN
表示將從外部傳遞的值,OUT
表示將用於返回過程外的值的參數。AS
關鍵字而不是IS
關鍵字來建立存儲過程。例子
如下示例演示如何建立一個簡單的存儲過程,執行時它只顯示字符串「Hello World!」
在屏幕上。class
SET SERVEROUTPUT ON SIZE 99999; CREATE OR REPLACE PROCEDURE greetings AS BEGIN dbms_output.put_line('Hello World!'); END; / -- 執行存儲過程 exec greetings; -- 或者 EXECUTE greetings;
當使用SQL提示符執行上述代碼時,它將產生如下結果 -
獨立的存儲程序能夠經過兩種方式調用 -
EXECUTE
關鍵字能夠使用EXECUTE
關鍵字調用名爲「greetings」
的存儲過程以下 -
EXECUTE greetings;
上述調用將顯示結果爲 -
SQL> EXECUTE greetings; Hello World! PL/SQL 過程已成功完成。 SQL>
該過程也能夠從另外一個PL/SQL塊調用,例如 -
BEGIN greetings; END; /
執行上面示例代碼,獲得如下結果 -
SQL> BEGIN 2 greetings; 3 END; 4 / Hello World! PL/SQL 過程已成功完成。 SQL>
使用DROP PROCEDURE
語句刪除獨立存儲過程。刪除程序的語法是 -
DROP PROCEDURE procedure-name;
能夠使用如下語句刪除greetings
存儲過程程序 -
DROP PROCEDURE greetings;
下表列出了PL/SQL子程序中的參數模式 -
編號 | 參數模式 | 描述 |
---|---|---|
1 | IN |
IN 參數容許將值傳遞給子程序。它是一個只讀參數。在子程序中,IN 參數的做用如常數,它不能被賦值。能夠將常量,文字,初始化的變量或表達式做爲IN 參數傳遞。也能夠將其初始化爲默認值; 然而,在這種狀況下,從子程序調用中省略它。 它是參數傳遞的默認模式。參數經過引用傳遞。 |
2 | OUT |
OUT 參數返回一個值給調用程序。在子程序中,OUT 參數像變量同樣。 能夠更改其值並在分配該值後引用該值。實際參數必須是可變的,而且經過值傳遞。 |
3 | IN OUT |
IN OUT 參數將初始值傳遞給子程序,並將更新的值返回給調用者。 它能夠分配一個值,該值能夠被讀取。對應於IN OUT 形式參數的實際參數必須是變量,而不是常量或表達式。正式參數必須分配一個值。實際參數(實參)經過值傳遞。 |
IN和OUT模式 - 示例1
假設如下存儲過程須要求出兩個值中的最小值。這裏,存儲過程兩個輸入的數字使用IN
模式,並使用OUT
模式參數返回最小值。
SET SERVEROUTPUT ON SIZE 99999; DECLARE a number; b number; c number; PROCEDURE findMin(x IN number, y IN number, z OUT number) IS BEGIN IF x < y THEN z:= x; ELSE z:= y; END IF; END; BEGIN a:= 12; b:= 35; findMin(a, b, c); dbms_output.put_line('兩個數:12, 35中的最小值是 : ' || c); END; /
當上述代碼在SQL提示符下執行時,它會產生如下結果 -
兩個數:12, 35中的最小值是 : 12
IN和OUT模式 - 示例2
此過程計算傳遞值的值的平方。此示例顯示瞭如何使用相同的參數來接受值,而後返回另外一個結果。
SET SERVEROUTPUT ON SIZE 99999; DECLARE a number; PROCEDURE squareNum(x IN OUT number) IS BEGIN x := x * x; END; BEGIN a:= 11; squareNum(a); dbms_output.put_line(' Square of (23): ' || a); END; /
當上述代碼在SQL提示符下執行時,它會產生如下結果 -
實際參數(實參)能夠經過三種方式傳遞 -
位置符號
在位置符號中,能夠調用存儲過程以下 -
findMin(a, b, c, d);
在位置符號中,第一個實際參數代替第一個形式參數; 第二個實際參數代替第二個形式參數,依此類推。 所以,a
代替x
,b
代替y
,c
代替z
,d
代替m
。
命名符號
在命名符號中,實際參數與使用箭頭符號(=>
)的形式參數相關聯。調用存儲過程以下所示 -
findMin(x => a, y => b, z => c, m => d);
混合符號
在混合符號表示中,能夠在過程調用中混合使用符號; 然而,位置符號應在命名符號以前。
如下調用存儲過程的方式是合法的 -
findMin(a, b, c, m => d);
可是,如下這種是不合法的:
findMin(x => a, b, c, d);