• 从概念到示例—Oracle创建程序包


    一、程序包的相关知识
    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;
         /

  • 相关阅读:
    vscode英文显示设置为中文语言
    vscode各插件使用-背景图-scss
    公众号关联小程序
    js点击遮罩空白区域关闭,点击遮罩内元素不关闭
    swiper使用-点击跳转指定页
    小程序内部引导关注公众号实现方法
    jq赋值input值为空
    sass中代码使用
    Sources”参数中指定了多次。“Sources”参数不支持重复项
    将已存在小程序项目添加云开发配置
  • 原文地址:https://www.cnblogs.com/sunjie9606/p/2167424.html
Copyright © 2020-2023  润新知