• oracle包概述(一)【weber出品】


    一、PL/SQL包概述

    1. 什么是PL/SQL包:

    相关组件的组合:PL/SQL类型、变量,数据结构,和表达式、子程序: 过程和函数

    2. 包的组成部分:

    由两部分组成:

    包头

    包体

    3. 包的优点

    一次读取多个对象进入内存

    二、PL/SQL包的组件

    包头:公共部分:包内和包外的程序都可以访问

    包体:私有部分:包体定义的变量或者程序只能被本包内的程序调用

    1. 创建包头

    语法:

    CREATE [OR REPLACE] PACKAGE package_name IS|AS
        public type and variable declarations
        subprogram specifications
    END [package_name];

    OR REPLACE选项删除并且重新创建包

    在包头声明的变量初始化值默认为NULL

    所有在包头声明的结构,对于所有授予该包权限的用户都是可见的


    包声明示例: comm_pkg

    CREATE OR REPLACE PACKAGE comm_pkg IS
      std_comm NUMBER := 0.10;  --initialized to 0.10
      PROCEDURE reset_comm(new_comm NUMBER);
    END comm_pkg;
    /
    
    STD_COMM 是一个全局变量,初始为0.10
    
    RESET_COMM 用于重新设置奖金的过程,它在包体中被定义

    2. 创建包体

    语法:

    CREATE [OR REPLACE] PACKAGE BODY package_name IS|AS
        private type and variable declarations
        subprogram bodies
    [BEGIN initialization statements]
    END [package_name];

    OR REPLACE选项删除并且重新重建包体

    包体中定义的标识符是私有的,包体之外不可见

    所有的私有结构,在引用前必须先声明

    公共结构在包体中是可见的

    create or replace package comm_pkg is
      std_comm number := 0.10;
      procedure reset_comm(new_comm number);
    end;
    
    create or replace package body comm_pkg is
      function validate(comm number) return boolean is
        max_comm employees.commission_pct%type;
      begin
        select max(commission_pct) into max_comm from employees;
        return(comm between 0 and max_comm);
      end validate;
    
      procedure reset_comm(new_comm number) is
      begin
        if validate(new_comm) then
          std_comm := new_comm;
        else
          raise_application_error(-20210, 'Bad Commission');
        end if;
      end reset_comm;
    end;

    三、调用包中的子程序

    在同一个包内调用子程序:

    CREATE OR REPLACE PACKAGE BODY comm_pkg IS ...
      PROCEDURE reset_comm(new_comm NUMBER) IS
      BEGIN
        IF validate(new_comm) THEN
          std_comm := new_comm;
        ELSE ... 
        END IF;
      END reset_comm;
    END comm_pkg;

    在sqlplus中调用包中的过程:

    SQL> execute comm_pkg.reset_comm(0.15);
    SQL> set serveroutput on;
    SQL> ed
    
    declare
    v_std_comm comm_pkg.std_comm%type;
    begin
    v_std_comm := comm_pkg.std_comm;
    dbms_output.put_line(v_std_comm);
    end;
    /
    
    结果:
    SQL> /
    std_comm:.15
    PL/SQL procedure successfully completed

    在不同模式下调用包内的过程

    SQL> conn hr/hr
    
    SQL> grant execute on comm_pkg to scott;
    
    
    conn scott/tiger
    
    
    SQL> execute comm_pkg.reset_comm(0.36);
    PL/SQL procedure successfully completed
    
    SQL> 
    SQL> declare
      2    v_std_comm comm_pkg.std_comm%type;
      3  begin
      4    v_std_comm := comm_pkg.std_comm;
      5    dbms_output.put_line('v_std_comm:' || v_std_comm||'std_comm:' || comm_pkg.std_comm);
      6  end;
      7  /
    v_std_comm:.36std_comm:.36
    PL/SQL procedure successfully completed

    注意:千万不要在sql窗口中写入这段话,不然执行过程是在sql中执行,全局变量存在于sql进程中吗,不会存在sql窗口中,所以在sql窗口中访问到的永远都是std_comm的初始值:0.10


    四、创建和使用无体包

    create or replace package global_consts is
      mile_2_kilo  CONSTANT NUMBER := 1.6093;
      kilo_2_mile  CONSTANT NUMBER := 0.6214;
      yard_2_meter CONSTANT NUMBER := 0.9144;
      meter_2_yard CONSTANT NUMBER := 1.0936;
    end;

    无体包内声明的变量时全局变量,包外的子程序或者匿名块都可以使用

    在匿名块中使用:

    BEGIN
      DBMS_OUTPUT.PUT_LINE('20 miles = ' || 20 * global_consts.mile_2_kilo ||
                           ' km');
    END;

    在子程序中调用:

    CREATE FUNCTION mtr2yrd(m NUMBER) RETURN NUMBER IS
    BEGIN
      RETURN(m * global_consts.meter_2_yard);
    END mtr2yrd;
    
    
    begin
    DBMS_OUTPUT.PUT_LINE(mtr2yrd(1));
    end;

    五、在数据字典中查看包的信息

    查看包头信息:

    SELECT text
      FROM user_source
     WHERE name = 'COMM_PKG'
       AND type = 'PACKAGE';

    查看包体信息:

    SELECT text
      FROM user_source
     WHERE name = 'COMM_PKG'
       AND type = 'PACKAGE BODY';

    六、使用包的优势

    1. 模块化: 封装相关的结构

    2. 更加容易维护: 将相关的逻辑功能组合到一起

    3. 使应用设计更加容易: 包头和包体的编译是分开进行的

    4. 隐藏信息:

    对于应用,只有声明部分是可见的

    包体的私有部分被隐藏并且不能被应用访问

    包体中的所有代码被隐藏

    5. 提高了性能:

    当包第一次被引用的时候,包内的所有内容全部被加载到内存中

    对于所有的用户来讲,在内存中只复制一次

    简化了依赖性

    6. 重载: 多个子程序相同的名

    七、删除包

    使用如下语法删除包头和包体:

    DROP PACKAGE package_name;
    
    删除包体语法:
    
    DROP PACKAGE BODY package_name; 
  • 相关阅读:
    C#中的Json序列化
    c#在sqlserver中使用EF框架
    Mvc中模拟模型
    localdb启动
    List泛型用法(半转载半原创)
    C#中真正的属性
    委托的简介、使用和简单事件
    类嵌套_list泛型_餐馆点菜例
    JavaIO
    JavaIO
  • 原文地址:https://www.cnblogs.com/yaoweber/p/3952220.html
Copyright © 2020-2023  润新知