PL/SQL - 包

  • 简述

    在本章中,我们将讨论 PL/SQL 中的包。包是将逻辑相关的 PL/SQL 类型、变量和子程序分组的模式对象。
    一个包将有两个强制性部分 -
    • 包规格
    • 包体或定义
  • 包规格

    规范是包的接口。这只是DECLARES可以从包外部引用的类型、变量、常量、异常、游标和子程序。换句话说,它包含有关包内容的所有信息,但不包括子程序的代码。
    放置在规范中的所有对象都被称为 public对象。任何不在包规范中但在包体中编码的子程序称为private 目的。
    以下代码片段显示了具有单个过程的包规范。您可以在一个包中定义多个全局变量和多个过程或函数。
    
    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;
    
    考虑一下,我们已经在我们的数据库模式中创建了上述包,以下程序使用 find_sal 的方法 cust_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; 
    /
    
    上面的例子使用了 nested table. 我们将在下一章讨论嵌套表的概念。
    在 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