PL/SQL之十 包

来源:互联网 发布:skyworth怎么连接网络 编辑:程序博客网 时间:2024/05/18 17:26

1.概述

   包是使用包名进行分组的PL/SQL语句块的集合。将逻辑上相关联的PL/SQL类型、变量常量、过程、函数、游标和异常封装在一起。将“包”看作一个“应用程序”。
   优势:模块化;更容易的应用设计;更好的性能;公共变量可在会话期间被所有子程序共享。

2.定义

   包头:
     --含有包的内容的相关信息(全局或公开变量的声明)。
     --若定义游标、子程序,则一定要在包体中实现;
     --可实现子程序重载。
     --语法:
create or replace PACKAGE package_name        is        [declarations of variables and types]        [specifications of cursors]        [specifications of modules]        end package_name;

   包体:
     --含有包头中所描述对象的实际可执行代码。也有包头中未声明对象的代码(称为私有对象)。
     --可以包含包头中未定义的常量变量、游标、子程序等,但在包外不可调用它们。
     --语法:
       Create or replace PACKAGE BODY package_name        is        [declarations of variables and types]        [specification and select statement of cursors]        [specification and body of modules]        [begin          executable statements]        [exception           exception handlers]        end package_name;

   关于编译:
     --包头重新编译后,包体会变成invalid,需做对应修改后再编译,包体状态才会变为valid。
     --包体重新编译后,包头不会变成invalid。
     -- alter package schema.package_name compile [package|specification|body]
       参数说明:
          package:包头和包体重新编译。
          specification:包头重新编译。
          body:包体重新编译

   包体的规则:
        游标和模块头部以及它们在包规范中的定义,必须是准确匹配的。
         不要在包体中重复包头中对变量、异常、类型和常量的声明。
        包规范中的声明任何元素都可以在包体中引用。引用语法:package_name.element.

3.示例

    包头(包规范):  
create or replace package manage_studentsas v_current_time date; --全局公有变量 v_currnet_time --存储过程声明 procedure find_name(i_student_id in student.student_id%type,                     o_first_name out student.FIRST_NAME%type,                     o_last_name out student.LAST_NAME%type); --函数声明 function id_is_good(i_student_id in student.STUDENT_ID%type)       return boolean;end manage_students;   

包体: 
create or replace package body manage_studentsas v_num constant number:=1; --私有常量 v_sys varchar2(10);--私有变量 --存储过程实现 procedure find_name(i_student_id in student.student_id%type,                     o_first_name out student.FIRST_NAME%type,                     o_last_name out student.LAST_NAME%type) is   v_student_id student.STUDENT_ID%type; begin       select first_name,last_name into o_first_name,o_last_name from student       where student_id=i_student_id; EXCEPTION       when others then              dbms_output.put_line('Error is finding student_id:'||v_student_id); end find_name;   --函数实现 function id_is_good(i_student_id in student.STUDENT_ID%type)       return boolean is   v_id_cnt number; begin       select count(*) into v_id_cnt from student where student_id=i_student_id;       return 1=v_id_cnt; exception       when others then return false; end id_is_good; --包体自忆的私有函数 function student_count_priv --此函数数是包体私有的       return number is   v_count number; begin       select count(*) into v_count from student;       return v_count; exception       when others then return (0); end student_count_priv; --给全局变量赋值 begin        select sysdate into v_current_time from dual;end manage_students;