1. 程式人生 > >10、PL/SQL儲存過程

10、PL/SQL儲存過程

子程式是執行特定任務的程式單元/模組。 這些子程式組合起來形成更大的程式。這種做法被稱為“模組化設計”。 子程式可以被稱為呼叫程式的另一個子程式或程式呼叫。

可以在以下幾個地方中建立一個子程式 -

  • 在模式(schema)級別中
  • 一個程式包中
  • 在PL/SQL塊中

在模式(schema)級別中,子程式是一個獨立的子程式。它是使用CREATE PROCEDURECREATE FUNCTION語句建立的。它儲存在資料庫中,可以使用DROP PROCEDUREDROP FUNCTION語句進行刪除。

在包中建立的子程式是打包的子程式。它儲存在資料庫中,只有當使用DROP PACKAGE語句刪除程式包時,才能將其刪除。

PL/SQL子程式被命名為可以使用一組引數呼叫的PL/SQL塊。 PL/SQL提供兩種子程式 -

  • 函式 - 這些子程式返回單個值; 主要用於計算和返回值。
  • 儲存過程(程式) - 這些子程式不直接返回值; 主要用於執行動作。

PL/SQL子程式的部分

每個PL/SQL子程式都有一個名稱,也可能有一個引數列表。 像匿名PL/SQL塊一樣,命名塊也將具有以下三個部分 -

編號 部分 描述
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;

其中,

  • procedure-name是要建立的儲存過程的名稱。
  • [OR REPLACE]選項允許修改現有的過程。
  • 可選引數列表包含引數的名稱,模式和型別。IN表示將從外部傳遞的值,OUT表示將用於返回過程外的值的引數。
  • procedure-body包含可執行部分。
  • 使用AS關鍵字而不是IS關鍵字來建立儲存過程。

例子 以下示例演示如何建立一個簡單的儲存過程,執行時它只顯示字串“Hello World!”在螢幕上。

SQL> create or replace procedure greetings
  2  as 
  3  begin
  4         dbms_output.put_line('Hello World!');
  5  end;
  6  /
Procedure created

SQL> exec greetings;
PL/SQL procedure successfully completed


SQL> exec greetings;
Hello World!
PL/SQL procedure successfully completed

執行獨立程式

獨立的儲存程式可以通過兩種方式呼叫 -

  • 使用EXECUTE關鍵字
  • 從PL/SQL塊呼叫過程的名稱

可以使用EXECUTE關鍵字呼叫名為“greetings”的儲存過程如下 -

SQL> execute greetings;
Hello World!
PL/SQL procedure successfully completed

該過程也可以從另一個PL/SQL塊呼叫,例如 -

SQL> begin
  2          greetings;
  3  end;
  4  /
Hello World!
PL/SQL procedure successfully completed

刪除獨立儲存過程

使用DROP PROCEDURE語句刪除獨立儲存過程。刪除程式的語法是 -

DROP PROCEDURE procedure-name;

可以使用以下語句刪除greetings儲存過程程式 -

SQL> drop procedure greetings;
Procedure dropped

PL/SQL子程式中的引數模式

下表列出了PL/SQL子程式中的引數模式 -

編號 引數模式 描述
1 IN IN引數允許將值傳遞給子程式。它是一個只讀引數。在子程式中,IN引數的作用如常數,它不能被賦值。可以將常量,文字,初始化的變數或表示式作為IN引數傳遞。也可以將其初始化為預設值; 然而,在這種情況下,從子程式呼叫中省略它。 它是引數傳遞的預設模式。引數通過引用傳遞。
2 OUT OUT引數返回一個值給呼叫程式。在子程式中,OUT引數像變數一樣。 可以更改其值並在分配該值後引用該值。實際引數必須是可變的,並且通過值傳遞。
3 IN OUT IN OUT引數將初始值傳遞給子程式,並將更新的值返回給呼叫者。 它可以分配一個值,該值可以被讀取。對應於IN OUT形式引數的實際引數必須是變數,而不是常量或表示式。正式引數必須分配一個值。實際引數(實參)通過值傳遞。

IN和OUT模式 - 示例1

假設以下儲存過程需要求出兩個值中的最小值。這裡,儲存過程兩個輸入的數字使用IN模式,並使用OUT模式引數返回最小值。

SQL> declare 
  2          a number;
  3          b number;
  4          c number;
  5  procedure findMin(x in number, y in number, z out number) is 
  6  begin
  7            if x < y then
  8               z := x;
  9            else 
 10              z := y;
 11           end if;
 12  end;
 13  begin
 14           a :=12;
 15           b :=15;
 16           findMin(a,b,c);
 17           dbms_output.put_line('兩個數:12,15中的最小值是:' || c);
 18  end;
 19  /
兩個數:12,15中的最小值是:12
PL/SQL procedure successfully completed

IN和OUT模式 - 示例2

此過程計算傳遞值的值的平方。此示例顯示瞭如何使用相同的引數來接受值,然後返回另一個結果。

SQL> declare 
  2          a number;
  3  procedure squareNum(x in out number) is 
  4  begin
  5            x := x * x;
  6  end;
  7  begin
  8            a := 11;
  9            squareNum(a);
 10            dbms_output.put_line(' Square of (23): ' || a);
 11  end;
 12  /
 Square of (23): 121
PL/SQL procedure successfully completed

傳遞引數的方法

實際引數(實參)可以通過三種方式傳遞 -

  • 位置符號
  • 命名符號
  • 混合符號

位置符號

在位置符號中,可以呼叫儲存過程如下 -

findMin(a, b, c, d);

在位置符號中,第一個實際引數代替第一個形式引數; 第二個實際引數代替第二個形式引數,依此類推。 因此,a代替xb代替yc代替zd代替m

命名符號

在命名符號中,實際引數與使用箭頭符號(=>)的形式引數相關聯。呼叫儲存過程如下所示 -

findMin(x => a, y => b, z => c, m => d);

混合符號

在混合符號表示中,可以在過程呼叫中混合使用符號; 然而,位置符號應在命名符號之前。

以下呼叫儲存過程的方式是合法的 -

findMin(a, b, c, m => d);

但是,以下這種是不合法的:

findMin(x => a, b, c, d);