第八章理论课触发器和内置程序包

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《Oracle数据库应用》理论课
触发器和内置程序包
⏹本章技能目标
◆理解和应用触发器
◆了解内置程序包
1.触发器
触发器是特定事件出现的时候,自动执行的代码块。

类似于存储过程,触发器与存储过程的区别在于:存储过程是由用户或应用程序显式调用的,而触发器是不能被直接调用的。

触发器可以用于加载Oracle的默认功能,提供高度可定制的数据库,触发器能够执行的功能有:
1、允许/限制对表的修改
2、自动生成派生列,比如自增字段
3、强制数据一致性
4、提供审计和日志记录
5、防止无效的事务处理
6、启用复杂的业务逻辑
触发器与特定的表或视图相关联,用于检查对表或视图所做的数据修改。

无论正在执行操作的用户身份如何,触发器都能够在它们执行操作时生效。

当INSERT,DELETE,UPADTE等事件发生在表或视图中时,就会激活触发器的代码。

before和after:指在事件发生之前或之后激活触发器。

instead of:如果使用此子句,表示可以执行触发器代码来代替导致触发器调用的事件。

insert、delete和update:指定构成触发器事件的数据操纵类型,update还可以制定列的列表。

referencing:指定新行(即将更新)和旧行(更新前)的其他名称,默认为new和old。

table_or_view_name:指要创建触发器的表或视图的名称。

for each row:指定是否对受影响的每行都执行触发器,即行级触发器,如果不使用此子句,则为语句级触发器。

when:限制执行触发器的条件,该条件可以包括新旧数据值得检查。

declare---end:是一个标准的PL/SQL块。

例1演示如何在SCOTT模式的EMP表上创建触发器。

例1:
SHOW ERRORS。

1.1触发器的组成部分
触发器由三部分组成:
●触发器语句(事件)
⏹定义激活触发器的DML 事件和DDL 事件
●触发器限制
⏹执行触发器的条件,该条件必须为真才能激活触发器
●触发器操作(主体)
⏹包含一些SQL 语句和代码,它们在发出了触发器语句且触发限制的值为真时运

触发器语句
触发器语句是那些可以导致触发器的事件,即在表或视图上执行的INSERT,DELETE,UPADTE 之类的DML语句,在模式对象上执行的DDL语句或数据库事件。

EMP表的deptno列进行UPADTE时。

而且触发器将在受到影响的每一行上执行一次。

但是触发器是否真正的执行还要检查触发器的条件,只有满足限制条件才会执行。

触发器限制
触发器限制条件包含一个布尔表达式,该值必须为“真”才能激活触发器。

如果该值为“假”
或“未知”,将不运行触发器操作。

这就是说,如果列deptno的新值不等于40,触发器将会执行。

触发器操作
触发器操作是触发器的主体,包含一些SQL语句和代码。

这些代码在执行触发器语句且触发器限制条件的值为“真”时运行。

行级触发器允许触发操作中的语句访问行的列值。

例1中的触发器操作如下面的代码所示
以上这段代码将列comm新增设置为0。

现在,来测试此触发器产生的效果。

例2演示了如何在EMP表中插入记录。

例2:
上述语句在EMP表中插入了两条记录。

并为每行记录指定了COMM列的值。

用户在表中插入了值,这将激活前面创建的触发器。

可以看到,插入第一行数据时指定了COMM列的值为600。

但是DEPTNO的值不等于40,所以会激活触发器,COMM列的值被设置为0。

插入第二行记录时,由于DEPTNO的值等于40,不满足触发器限制条件,所以触发器不执行,用户指定的COMM列的值插入到数据库中。

1.2触发器类型
Oracle具有不同类型的触发器,可以实现不同的任务。

这些触发器类型包括:
语句触发器,行触发器,INSTEAD OF 触发器,模式触发器,数据库级触发器
分类如下图:
DDL 触发器:在模式中执行DDL 语句时执行
数据库级触发器:在发生打开、关闭、登录和退出数据库等系统事件时执行
DML 触发器:在对表或视图执行DML语句时执行
语句级触发器:无论受影响的行数是多少,都只执行一次
行级触发器:对DML语句修改的每个行执行一次
INSTEAD OF 触发器:用于用户不能直接使用DML 语句修改的视图
具体叙述如下:
1.行级触发器
行级触发器对DML语句影响的每个行执行一次,例如:UPADTE语句影响多行,就会对每行都激活一次触发器。

行触发器是触发器中最常用的一种。

通常用于数据库审计和实现复杂的业务逻辑。

可以在CREATE TRIGGER命令中指定FOR EACH ROW子句创建行级触发器。

由于触发器是事件驱动的,因此可以设置触发器在这些事件之前或之后执行,即在执行DML 语句之前或之后执行。

在触发器中,可以引用DML语句中涉及的旧值和新值。

“新”是指由DML语句创建的数据值(如插入记录中的列)。

执行DML语句之前的值的默认名称是:old ,之后的值是:new。

insert 操作只有:new
delete 操作只有:old
update 操作两者都有
如果需要通过触发器在插入行中设置一个列值,就应该使用BEFORE INSERT 触发器访问新值。

使用AFTER INSERT不允许设置插入值,因为该行已经插入表中。

在审计应用程序中经常使用AFTER行级触发器,直到行被修改才会触发它们。

行的成功修改表明此行已经通过该表定义的完整性约束。

例3演示了行级触发器的应用。

例3:
例3先创建一个测试表TEST_TRG,接着创建一个序列SEQ_TEST,然后创建一个触发器自动生成ID列的值,并禁止UPADTE表的ID列。

最后,向测试表中插入3条记录。

现在,使用以
上述语句的输出结果是:
可以看出,表的ID列的值是由触发器自动产生的,而不是用户在插入命令中指定值。

提示:如果一个触发器由多种语句的触发,可以使用INSERTING,UPDATING,DELETING 条件谓词来检查,如果值为“真”,那么就是相应得语句类型激活了该触发器。

条件谓词只能在
2.语句级触发器
语句级触发器对每个DML语句执行一次。

例如,如果一条INSERT语句在表中插入200行,那么这个表上的INSERT语句级触发器只执行一次。

语句级触发器不常用于与数据库相关的活动,通常用于强制实施在表上执行操作的额外安全性措施。

语句级触发器是CREATE TRIGGER命令创建的触发器的默认类型。

例4演示了如何创建语法级触发器。

例4-1需要对在表上进行DML操作的用户进行安全检查,看是否具有合适的特权。

3.INSTEAD OF 触发器
INSTEAD OF 触发器是在视图上而不是在表上定义的触发器,它是用来替换所使用实际语句的触发器。

这样的触发器可以用于克服Oracle在任何视图上设置的限制。

允许用户修改不能直接使用DML语句修改的视图。

以下是对INSTEAD OF 触发器的一些限制。

它们只能在行级使用,而不能在语句级使用。

它们只能应用于视图,而不能应用于表。

如果有需要同时向两个表插入值的情况,可以通过使用INSTEAD OF 触发器来实现。

例5演示了在表order_master和order_detail上创建视图以完成同时向两个表中插入值的操作。

例5:
上述语句创建了两个表order_master,和order_detail上的联接视图ord_view。

在创建视图之后,
入了行。

4.模式触发器
可以在模式级的操作上建立触发器,如:CREATE,ALTER,DROP,GRANT,REVOKE和TRUNCA TE等DDL语句。

用户可以创建触发器来防止删除自己创建的表。

模式触发器提供的主要功能是阻止DDL操作以及发生DDL操作时提供额外的安全监控。

当在表,视图,过程,函数,索引,程序包,序列和同义词等模式对象执行CREATE,DROP 和ALTER命令时,会激活DDL触发器。

例6演示如何对用户所删除的所有对象进行日志记录。

5.数据库触发器
可以创建在数据库事件上的触发器。

包括启动,关闭,服务器错误,登录和注销等。

这些事件都是实例范围的。

不与特定的表和视图关联。

可以使用这种类型的触发器自动进行数据库维护和统计。

下面给出一个简单的示例。

1.3启用、禁用触发器
触发器一旦创建就会立即生效,有时可能需要临时禁用触发器,最常见的原因就是涉及数据加载。

用于启动和禁用触发器的语法如下:
1.4删除触发器
下面演示如何删除触发器biu_emp_deptno。

1.5查看有关触发器的信息
要查看有关触发器的信息,可使用USER_TRIGGERS 数据字典视图,此视图包含有关触发器
下面的案例演示如何查看有关触发器的信息。

例8:
2.内置程序包
Oracle提供了许多内置程序包,它们用于扩展数据库的功能。

在开发应用程序时,可以利用这些程序包。

数据库用户SYS拥有Orcale提供的所有程序包。

它们被定义为公有同义词,并将执行权限授予了PUBLIC用户组,任何用户都可以访问它们。

Oracle提供的程序包的部分列表见下表。

一些内置程序包
下面简单介绍几个常用的内置程序包。

2.1DBMS_OUTPUT
DBMS_OUTPUT程序包允许显示PL/SQL块和子程序的输出结果。

这样便于测试和调试它们。

PUT和PUT_LINE过程将信息输出到SGA中的缓存区。

通过调用过程GET_LINE或通过SET SERVEROUTPUT ON。

可以显示缓存区的信息。

默认缓存区大小是2000字节。

最小值是2000,最大值是1,000,000。

DBMS_OUTPUT包有以下常用过程。

ENABLE
ENABLE过程用来启用对PUT,PUT_LINE和NEW_LINE等过程的调用,它只有一个输入参数,即缓存区大小(BUFFER_SIZE)。

缓存区大小的输入值用于设置默认缓存的信息量。

调用ENABLE将清除任何已废弃会话中缓存的数据。

DISABLE
DISABLE没有输入和输出。

DISABLE用于禁用对PUT,PUT_LINE和NEW_LINE的所有调用。

调用DISABLE过程还可清除缓存区中的任何剩余信息。

PUT
PUT有一个输入参数。

此参数被重载以接受VRACHAR2,NUMBER和DATE值。

PUT用于在缓存区中存储一条信息。

TO_CHAR将使用默认格式设置格式化这些项。

PUT_LINE
PUT_LINE有一个输入参数。

此参数被重载以接受VRACHAR2,NUMBER和DATE值。

如果这些值是混合使用,则必须使用TO_CHAR函数.PUT_LINE过程用于在缓存区中存储一条信息。

后接一个行结束标记。

NEW_LINE
NEW_LINE没有参数。

它用于向缓存区中添加换行符, 换行符充当结束标记,对PUT_LINE或NEW_LINE的每次调用都将产生一行。

例9演示了DBMS_OUTPUT包的用法。

上述语句的输出结果是:
2.2DBMS_LOB
DBMS_LOB程序包包含用于处理大型对象的过程和函数.在Orcale中,LOB分为以下几种类型:BLOB(二进制大对象),CLOB(字符大对象),BFILE(外部存储的二进制文件).大部分LOB操作由此程序包提供.
DBMS_LOB包有如下的一些过程和函数.
APPEND:此过程用于将在src_lob参数中指定的BLOB或CLOB追加到在dest_lob参数中指定的BLOB或CLOB.
COPY:此过程用于从指定的偏移量值开始将源BLOB或CLOB复制到目的BLOB或CLOB. ERASE:此过程用于删除lob_loc指定的BLOB或CLOB中指定偏移量(offset)处开始的指定量(amount)的部分.
GETLENGTH:此函数返回指定的BLOB,CLOB或BFILE的长度,并使用适合于该类型的单位.
INSTR:此函数从LOB数据中查找子串.
READ:此过程从LOB数据中读取指定长度数据到缓存.
SUBSTR:. :此函数从LOB数据中取子串
WHITE:此过程用于将指定数量的数据写入LOB.
以下是一些专门操作BFILE类型文件以进行读取.
FILEOPEN:此过程用于打开BFILE类型文件以进行读取.
FILEGETNAME:此过程用于接受文件定位器值并返回文件目录别名和文件名.
FILECLOSE:此过程用于关闭指定的BFILE.
FILEISOPEN:该函数用于判断BFILE文件是否已打开.
DBMS_LOB程序的使用参见第五章的相关案例)
2.3DBMS_XMLQUERY
DBMS_XMLQUERY包用于将查询结果转换为XML格式。

例10演示了DBMS_XMLQUERY包的用法。

上例声明了一个CLOB数据类型的result变量,以及V ARCHAR2类型的xmlstr和line两个变量。

其中getxml函数用于将查询结果转换为XML格式,SUBSTR函数检索子字符串,32767值指定要从CLOB数据类型读取的最大字节数。

检索到的字符串存储在xmlstr变量中。

LOOP 块循环执行,每次从xmlstr中读取一行。

INSERT函数返回一个字符串在另一个字符串中首次出现的位置。

在此,该函数返回换行符在字符串中的位置,直到遇到下一行。

上述语句的输出结果如下所示:
2.4DBMS_RANDOM
DBMS_RANDOM包可以用来生成随机数,该包的RANDOM函数返回一个8位的随机整数,该整数的正负也是随机的。

例11演示了产生10个1到100得随机数。

例12:
DBMS_RANDON.STRING(参数一,参数二);
其中:
参数二是指生成随机数的长度。

参数一有以下几种形式:
1)’u’生成的是大写字母
2) ’l’生成的是小写字母
3)’a’生成的是大小写混合
4)’x’生成的是数字和大写字母混合
5)’p’任何形式(连特殊符号都行);
2.5UTL_FILE
UTL_FILE 包用于从PL/SQL程序中读写操作系统文本文件,如XML文件。

UTL_FILE包对文件的读写过程与编程语言(如C语言)的流操作类似,一般的过程是打开,读或写,关闭。

UTL_FILE包要求文件所在位置是基于ORACLE的DIRECTORY对象指定的目录。

不能直接使用文件的绝对路径。

要使用UTL_FILE包必须先将创建目录对象与操作系统得目录关联起来。

创建目录对象需要有相关的权限,以SYSTEM用户执行如下命令。

上例首先创建了目录对象TEST_DIR关联到服务器上的'C:\DEVELOP文件夹,在使用此目录对象之前必须保证操作系统中已存在此文件夹。

然后,将操作此目录对象的授权SCOTT用户。

以SCOTT用户执行以下命令。

例15通过UTL_FILE将DBMS_XMLQUERY包的查询结果保存到文件中。

例16演示如何从XML文件中读取文本文件。

例16:
总结
触发器是当特定事件出现时自动执行的存储过程
触发器分为DML 触发器、DDL 触发器和数据库级触发器三种类型
DML 触发器的三种类型包括行级触发器、语句级触发器和INSTEAD OF 触发器 一些常用的内置程序包:
⏹DBMS_OUTPUT 包输出PL/SQL 程序的调试信息
⏹DBMS_LOB 包提供操作LOB 数据的子程序
⏹DBMS_XMLQUERY 将查询结果转换为XML 格式
⏹DBMS_RANDOM 提供随机数生成器
⏹UTL_FILE 用于读写操作系统文本文件
一、练习
1使用()命令可查看在创建触发器时发生的编译错误。

A VIEW ERRORS
B SHOW ERRORS
C DISPLAY ERRORS
D CHECK ERRORS
2()包用于显示PL/SQL块和存储过程中的调试信息。

A DBMS-OUTPUT
B DBMS-STANDARD
C DBMS-INPUT
D DBMS-SESSION
3()触发器允许触发操作中的语句访问行的列值。

A 行级
B 语句级
C 模式
D 数据库级
4要审计用户执行的CREA TE、DROP和ALTER等DDL语句,应该创建()触发器。

A 行级
B 语句级
C INSTEA
D OF
D 模式
E 数据库级
5 Oracle的内置程序包由()用户所有。

A SYS
B SYSTEM
C SCOTT
D PUBLIC
6()程序包用于读写操作系统文本文件。

A DBMS-OUTPUT
B DBMS-LOB
C DBMS-RANDOM
D UTL-FILE
二、作业
1创建一个触发器,无论用户插入新记录,还是修改EMP表的JOB列,都将用户指定的JOB 列的值转换成大写。

2 创建一个触发器,禁止用户删除DEPT表中的记录。

提示:创建语句触发器。

相关文档
最新文档