现在的位置: 首页 > 综合 > 正文

Oracle 创建程序包

2013年03月20日 ⁄ 综合 ⁄ 共 5607字 ⁄ 字号 评论关闭

一、程序包的相关知识
1.定义与说明
  a. 相关对象的封装
  b. 程序包的各部分
    - 程序包规格说明
          声明子程序
   - 程序包主体
          定义子程序

2.使用程序包的优点
  - 模块化
  - 更轻松的应用程序设计
  - 信息隐藏
  - 新增功能
  - 性能更佳

3.公有项和私有项的区别
 公有项:在程序包说明部分定义的变量、过程、函数
 私有项:在程序包主体部分定义的变量、过程、函数

 公有项                          私有项
可以在程序包之外引用         不能在程序包之外引用
是在程序包规格说明中定义的   是在程序包主体中定义的
用于全局目的                 用于局部目的

二、程序包创建说明
 1.程序包规格说明
    (1)、使用Create Package命令进行创建
    (2)、包含公用对象和类型
    (3)、声明类型、常量、变量、异常、游标和子程序
    (4)、可以在没有程序包主题的情况下存在
    (5)、可以重载
        - 程序包中的多个子程序可以具有相同的名称
        - 它们的形参是不同的
        - 只能位于打包的子程序中
        - 限制
           a. 如果子程序的参数仅名称或模式不同,则不能重载
           b. 不能基于其返回类型重载子程序

 2.程序包主体
    (1)、使用Create Package body 命令进行创建
    (2)、包含子程序和游标的定义
    (3)、包含私有声明
    (4)、不能在没有程序包规格说明的情况下独立存在

 3.程序包的调用
    包名.类型名;
    包名.函数名[参数表];
    包名..过程名[参数表];
    (1)、 Package-name.type-name
    (2)、 Package-name.object-name 
    (3)、 Package-name.subprogram-name
     其中,Package-name 是程序包名称,type-name是类型名称,
           object-name是对象名称,subprogram-name 是子程序名称
   --示例
     DBMS_output.put_line(Hello);
    (4)、对于返回参数是游标类型的调用(如:引用游标)
       set  autoprint on  --打开Sqlplus输出
       variable tempCur RefCursor;  --定义一个宿主类型的引用游标变量
       exec StudentPackage.ReturnStudent(:tempCur);  --执行带有引用游标的过程 注意使用宿主类型的变量前面要加“:”符号
 
4. 有关子程序和程序包的信息
   A.数据字典
    User_objects  用于检查对象是否存在
    User_source   用于获取对象的代码

   B. 包的修改和删除
     Alter Package [Body] 包名
     Alter Package Body StudentPackage;
     Drop  Package [Body] 包名
     Drop  Package Body StudentPackage;

5. 创建格式
  A.创建包规格部分
   格式:Create [or replace] Package 包名
         IS|AS
          变量声明;
          类型定义;
          异常声明;
          游标声明;
          函数说明;
          过程说明;
          Pragma restrict_references(过程名或函数名,WNDS[,WNPS][,RNDS][,RNPS]) --编译指令 限定函数的操作
        End [包名];

  B.创建包主体部分
   格式: Create [or replace] package body 包主体名 --包主体名一定要是已经定义的包名
        IS|AS 
        变量声明;   --具体的实现部分
        类型定义;
        异常声明;
        游标声明;
        函数说明;
        过程定义;
        End [包主体名];
   
6. 示例

 示例1.创建程序包的规格说明部分
   Create or replace Package StudentPackage
   is
     Type curRefStudent is  Ref Cursor Return Student%rowtype;
     Procedure SelectStudent(FindID in Student.stuid%type);
     Procedure InsertStudent(NewStudent in Student%rowType);
     Procedure UpdateStudent(NewStudent in Student%rowType);
     Procedure DeleteStudent(DelID in Student.stuid%type);
     Procedure ReturnStudent(inOutstu in out curRefStudent);
     Function  RegurnRecordCount Return Number;
  End studentPackage;
 示例2.创建程序包的主体部分
   Create or replace Package Body StudentPackage IS
   Procedure SelectStudent(FindID in Student.stuid%type) as  --注意没有Create
   /*实现查询过程的定义*/
    Cursor findCur is select * from student where stuid=FindID;
   Begin
      For S in FindCur Loop
         DBMS_output.put_line(S.stuID||' '||s.StuName||' '||S.Sex);
      End Loop;
   Exception
     When No_Data_Found Then
       DBMS_output.Put_Line('没有查到ID为'||FindID||'的记录!');
     When Others Then
       DBMS_output.Put_Line('查询过程中发生意外情况');
   End SelectStudent;  --结束查询过程

   /*实现插入过程的定义*/
   Procedure InsertStudent(NewStudent in Student%rowType) as
    iRec Integer;
    Not_Exists_Student Exception;  --预定义异常
    Begin
       Select count(*) into iRec from student where stuid=NewStudent.stuID;
       IF iRec>0 Then
       Raise Not_Exists_Student;
       Else
       insert into student values(NewStudent.stuid,NewStudent.stuName,NewStudent.sex);
       commit;
       End IF;
    Exception
     When Not_Exists_Student Then
       DBMS_output.Put_Line('要插入的编号:'||NewStudent.stuid||'的记录已经存在');
     When Others Then
       DBMS_output.Put_Line('插入记录操作过程中出现错误');
    End InsertStudent;--结束插入过程

   /*实现更新过程的定义*/
   Procedure UpdateStudent(NewStudent in Student%rowType) as
   iRec Integer;
   Begin
      select Count(*) into iRec From student Where stuid=NewStudent.stuid;
      IF iRec =0 Then
         DBMS_output.Put_Line('编号为:'||NewStudent.stuid||'的记录不存在,修改失败');
      ELSE
         Update student Set Stuname=NewStudent.stuName,Sex=NewStudent.Sex
         WHERE stuid=NewStudent.stuID;
         Commit;
     End IF;
   Exception
       When No_Data_Found Then
          DBMS_output.Put_Line('编号为:'||NewStudent.stuID||'的记录不存在,修改失败');
       When Others Then
           DBMS_output.Put_Line('执行修改操作时发生意外情况,修改未成功');
   End  UpdateStudent;--结束修改过程

   /*实现删除过程的定义*/
   Procedure DeleteStudent(DelID in Student.stuid%type) as
     iRec Integer;
   Begin
      Select Count(*) into iRec From Student Where stuID=DelID;
      IF iRec=0 Then
        DBMS_output.Put_Line('编号为:'||DelID||'的记录不存在,删除操作时未成功');
      ELSE
        Delete From student Where   stuid=DelID;
        Commit;
         DBMS_output.Put_Line('删除成功!');
      End IF;
   Exception
     When Others Then
          DBMS_output.Put_Line('执行删除操作时发生意外情况,删除未成功');
   End DeleteStudent;
  
    /*实现参数带有游标类型定义*/
    Procedure ReturnStudent(inOutstu in out curRefStudent) as
    Begin
        Open inOutstu For Select * from student;
    End ReturnStudent;

   /*实现函数定义*/
    Function RegurnRecordCount Return Number as
      RecCount number(10);
    Begin
       Select Count(*) into RecCount From student;
       Return recCount;
    Exception
       When Others Then
        DBMS_output.Put_Line('查询表中记录数时发生意外情况');
    End RegurnRecordCount; --结束函数的定义
   End  studentPackage;--结束包   

 示例3:调用包
    1. 调用studentPackage包中的InsertStudent过程
      Declare
         newStu  Student%RowType;
      Begin
         newStu.stuID:='1001';
         newStu.stuName:='张三';
         newStu.sex:='男';
         studentPackage.InsertStudent(newStu);
      End;
      /
   2. 调用studentPackage包中的UpdateStudent过程
      Declare
          newStu Student%RowType;
      Begin
          newStu.stuID:='1001';
          newStu.stuName:='李四';
          newStu.sex:='女';
          studentPackage.UpdateStudent(newStu);
      Exception
          When Dup_Val_On_Index Then
            DBMS_output.Put_Line('唯一约束被破坏');
          When Others Then
            DBMS_output.Put_Line('更新过程出现错误');
      End;
       /
   3. 调用studentPackage包中的DeleteStudent过程
     Begin
          studentPackage.DeleteStudent('1001');
     End;
     /
   4. 调用studentPackage包中的ReturnRecordCount函数
     Begin
         DBMS_output.put_Line(studentPackage.ReturnRecordCount);
     End;
     /

抱歉!评论已关闭.