Oracle笔记(五)

[包(Package)的设计与开发]

一、什么是包?
    把一些相关的存储过程、函数、变量、光标、例外等组合在一起形成的对象叫包。包由包的说明部分及包体两部分组成。定义在包说明部分的是公共元素,定义在包体的部分是私有元素。

二、使用包的优点:     
   1、规范化程序设计
   2、方便过程及函数的组织
   3、便于管理:包的授权只需一次完成
   4、优化系统性能:整个包作为一个整体一次调入内存。


三、包的开发步骤:
1、创建包的说明部分:Create package
2、创建包体部分:Create package body
3、在SQL*Plus中运行创建包
4、在存储过程、其它应用中调用。
在SQL*Plus中调用方法:SQL> exec 包名.过程名;

在存储过程、函数、其它应用中调用方法:包名.过程名;

四、创建包的语法:
1、创建包(说明部分):请参考PowerPoint教程:存储过程1.ppt[Page10]

2、创建包体(Create Package Body): 请参考PowerPoint教程:存储过程1.ppt[Page11]

3、例:请参考PowerPoint教程:存储过程1.ppt[Page12、13、14、15]

五、包的删除:
SQL> drop package 包名;
SQL> drop package body 包名;

查询包源代码:
SQL> select text from user_source where name = '包名';  // 包名大写。


[数据库触发器(Triggers)设计与开发]

一、 什么是触发器?
数据库触发器是一个存储的PL/SQL程序块,它与一个基表联系,当在表上执行特定的数据库维护(插入、删除、更新这三种操作)时,隐含地执行一个PL/SQL程序块。

二、触发器的作用:
 。防止非法的数据库操纵、维护数据库安全
 。对数据库的操作进行审计,存储历史数据
 。完成数据库初始化处理
 。控制数据库的数据完整性
 。进行相关数据的修改
 。完成数据复制
 。自动完成数据库统计计算
 。限制数据库操作的时间、权限等,控制实体的安全性
 
三、触发器的组成:
1、触发时间:触发器事件的时间次序(before, afer)[2]

2、触发事件:什么SQL语句会引起触发器触发(Insert, delete, update)[3]

3、触发子体:触发器触发时要执行的操作(一个完整的PL/SQL程序)

4、触发类型:触发器被执行的次数(语句级、行级)[2] //语句级只执行一次,行级会执行多次。

[*]一个表上最多可以创建12个不同类型的触发器:3*2*2 = 12

四、创建触发器注意事项:
1、在触发器中可以调用存储过程、包;在存储过程中不得调用触发器。

2、在触发器中不得使用commit, rollback, savepoint语句。

3、在触发器中不得间接调用含有commit, rollback, savepoint的语句的存储过程及函数。

五、创建语句级触发器:
语句级触发器: 请参考PowerPoint教程:存储过程1.ppt[Page19] 该触发器在数据库操作时只执行一次。
说明:
 。update中的of是可选项,用于指定语句要修改的列
 。要创建的触发器已经存在时,使用replace选项

//例1:before型触发器:
Create or replace trigger DelEmp
  before delete on emp
  Begin
   if (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18)
   then dbms_output.put_line('现在是非工作时间,请退出!!!');
   end if;
  End;

[触发器数据字典]
SQL> select table_owner, table_name,trigger_body from user_triggers where trigger_name='DELEMP';

//例2:After型触发器:
Create or replace trigger InsertEmp
after insert on emp     // 如果是before,就会比after的结果少一名。
Declare
 v_empcount number(7);
Begin
 select count(*) into v_empcount from emp;
 dbms_output.put_line('目前员工总数已达到:'|| v_empcount|| '名。');
End;


//例3:多个触发条件
Create or replace trigger ChangeEmp
before delete or insert or update on emp
Begin
   if (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between 8 and 18)
   then dbms_output.put_line('现在是非工作时间,请不要修改数据!!!');
   end if;
End;

// 更完善的写法:
Create or replace trigger ChangeEmp
  before delete or insert or update  on emp
  Begin
   if (DELETING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18))
   then dbms_output.put_line('现在是非工作时间,不要删除数据!');

   elsif (UPDATING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8 and 18))
   then dbms_output.put_line('现在是非工作时间,不要更新数据!');

   elsif (INSERTING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18))
   then dbms_output.put_line('现在是非工作时间,不要插入数据!');

   end if;
  End;

六、创建行级触发器:
等级触发器:增加选项for each row, 使触发器在每一行上触发。

1、创建行级触发器注意事项:
(1) 在行级触发器中,在列名前增加old表示该列修改前值,增加new表示该列修改后值。
(2) 在PL/SQL中引用时,前边增加冒号。
 
[例4: 行级触发器] //必须是对所有的行进行操作才行。
Create or Replace trigger UpdateEmp
Before update on emp
for each row
Begin
 dbms_output.put_line(:old.sal||'--------->'||:new.sal);
End;

[例5:保存历史数据,这种使用方法很重要,用来保存关键表的历史数据]
CReate or Replace trigger ChangeEmp
Before update or delete on emp
for each row
Begin
 Insert into oldemp(empno, ename,job,hiredate,sal)
 values(:old.empno,:old.ename,:old.job,sysdate,:old.sal);
End;

SQL> create table oldemp
 as select empno, ename,job,hiredate,sal from emp where 1>2;

[例6:修改外键]
Create or Replace trigger UpdateDept
after update on dept
for each row
Begin
 update emp
  set emp.deptno = :new.deptno
  where emp.deptno = :old.deptno;
End;

[例7:删除外键、删除相关数据]
Create or Replace trigger DeleteDept
before delete on dept
for each row
Begin
 delete from emp where deptno = :old.empno;
End;

七、触发器管理
1、使触发器失效:
SQL> alter trigger 触发器名称 disable;  // 失效
SQL> Alter Trigger 触发器名称 enable;  // 生效

SQL> Alter table 表名 DISABLE all triggers; // 一个表上的所有触发器失效
SQL> Alter table 表名 ENABLE all triggers; // 使一个表上的所有触发器生效

SQL> Drop Trigger 触发器名;  // 删除触发器;

你可能感兴趣的:(oracle,包,package,休闲,设计与开发)