位置:首頁 > 數據庫 > PL/SQL教學 > PL/SQL包

PL/SQL包

PL/SQL包是組邏輯相關的PL/SQL類型,變量和子程序模式對象。

程序包將有兩個強製性的部分:

  • 包裝規範定義

  • 包體或定義

包裝規範定義

規範是接口到包。它隻是聲明的類型,變量,常量,異常,遊標和子程序可從封裝外部引用。換句話說,它包含關於包的內容的所有信息,但不包括用於子程序的代碼。

置於規範的所有對象被稱為公共對象。任何子程序在封裝主體中冇有包定義但編碼被稱為私有對象。

下麵的代碼片段顯示了具有單一的程序包規範定義。一個包中可以定義的全局變量和多個程序或函數。

CREATE PACKAGE cust_sal AS
   PROCEDURE find_sal(c_id customers.id%type);
END cust_sal;
/

當上述代碼在SQL提示符執行時,它產生了以下結果:

Package created.

包主體

包體已經在包定義和其他私人聲明中聲明的各種方法,這是從代碼隱藏在包外的代碼。

CREATE PACKAGE BODY語句用於創建包體。下麵的代碼片段顯示了包體聲明上麵創建的cust_sal包。在前麵學習中,我們已經在數據庫中創建了一個CUSTOMERS表 - PL/SQL變量 這一章節。

CREATE OR REPLACE PACKAGE BODY cust_sal AS
   PROCEDURE find_sal(c_id customers.id%TYPE) IS
   c_sal customers.salary%TYPE;
   BEGIN
      SELECT salary INTO c_sal
      FROM customers
      WHERE id = c_id;
      dbms_output.put_line('Salary: '|| c_sal);
   END find_sal;
END cust_sal;
/

當上述代碼在SQL提示符執行時,它產生了以下結果:

Package body created.

使用包元素

訪問包元素(變量,過程或函數)的語法如下:

package_name.element_name;

想想,我們已經在上麵的數據庫模式中創建的包,下麵的程序是使用cust_sal包的find_sal方法:

DECLARE
   code customers.id%type := &cc_id;
BEGIN
   cust_sal.find_sal(code);
END;
/

當上麵的代碼在SQL提示符下執行,它提示輸入客戶ID,當輸入一個ID,它會顯示相應的薪酬如下:

Enter value for cc_id: 1
Salary: 3000

PL/SQL procedure successfully completed.

例子:

下麵的程序提供了一個更為完整的方案。我們將使用存儲在數據庫中的CUSTOMERS表的以下記錄:

Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  3000.00 |
|  2 | Khilan   |  25 | Delhi     |  3000.00 |
|  3 | kaushik  |  23 | Kota      |  3000.00 |
|  4 | Chaitali |  25 | Mumbai    |  7500.00 |
|  5 | Hardik   |  27 | Bhopal    |  9500.00 |
|  6 | Komal    |  22 | MP        |  5500.00 |
+----+----------+-----+-----------+----------+

包規範定義:

CREATE OR REPLACE PACKAGE c_package AS
   -- Adds a customer
   PROCEDURE addCustomer(c_id   customers.id%type,
   c_name  customers.name%type,
   c_age  customers.age%type,
   c_addr customers.address%type, 
   c_sal  customers.salary%type);
  
   -- Removes a customer
   PROCEDURE delCustomer(c_id  customers.id%TYPE);
   --Lists all customers
   PROCEDURE listCustomer;
 
END c_package;
/

當上麵的代碼在SQL提示符下執行,它會創建上述包,並顯示以下結果:

Package created.

創建包的主體部分:

CREATE OR REPLACE PACKAGE BODY c_package AS
   PROCEDURE addCustomer(c_id  customers.id%type,
      c_name customers.name%type,
      c_age  customers.age%type,
      c_addr  customers.address%type, 
      c_sal   customers.salary%type)
   IS
   BEGIN
      INSERT INTO customers (id,name,age,address,salary)
         VALUES(c_id, c_name, c_age, c_addr, c_sal);
   END addCustomer;
  
   PROCEDURE delCustomer(c_id   customers.id%type) IS
   BEGIN
       DELETE FROM customers
         WHERE id = c_id;
   END delCustomer;

   PROCEDURE listCustomer IS
   CURSOR c_customers is
      SELECT  name FROM customers;
   TYPE c_list is TABLE OF customers.name%type;
   name_list c_list := c_list();
   counter integer :=0;
   BEGIN
      FOR n IN c_customers LOOP
      counter := counter +1;
      name_list.extend;
      name_list(counter)  := n.name;
      dbms_output.put_line('Customer(' ||counter|| ')'||name_list(counter));
      END LOOP;
   END listCustomer;
END c_package;
/

上麵的例子中使用嵌套表,我們將在下一章討論。當上述代碼在SQL提示符執行時,它產生了以下結果:

Package body created.

使用包:

下麵的程序使用聲明並在包c_package中定義方法。

DECLARE
   code customers.id%type:= 8;
BEGIN
      c_package.addcustomer(7, 'Rajnish', 25, 'Chennai', 3500);
      c_package.addcustomer(8, 'Subham', 32, 'Delhi', 7500);
      c_package.listcustomer;
      c_package.delcustomer(code);
      c_package.listcustomer;
END;
/

當上述代碼在SQL提示符執行時,它產生了以下結果:

Customer(1): Ramesh 
Customer(2): Khilan 
Customer(3): kaushik    
Customer(4): Chaitali 
Customer(5): Hardik 
Customer(6): Komal
Customer(7): Rajnish
Customer(8): Subham
Customer(1): Ramesh 
Customer(2): Khilan 
Customer(3): kaushik    
Customer(4): Chaitali 
Customer(5): Hardik 
Customer(6): Komal
Customer(7): Rajnish

PL/SQL procedure successfully completed