oracle 触发器 学习笔记

触发器 是特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。

功能: 
1、 允许/限制对表的修改 
2、 自动生成派生列,比如自增字段 
3、 强制数据一致性 
4、 提供审计和日志记录 
5、 防止无效的事务处理 
6、 启用复杂的业务逻辑 
开始 
create trigger biufer_employees_department_id 
before insert or update 
of department_id 
on employees 
referencing old as old_value 
new as new_value 
for each row 
when (new_value.department_id<>80 ) 
begin 
:new_value.commission_pct :=0; 
end; 

触发器的组成部分: 
1、 触发器名称 
2、 触发语句 
3、 触发器限制 
4、 触发操作 
1、 触发器名称 
create trigger biufer_employees_department_id 
命名习惯: 
biufer(before insert update for each row) 
employees 表名 
department_id 列名 
2、 触发语句 
比如: 
表或视图上的DML语句 
DDL语句 
数据库关闭或启动,startup shutdown 等等 
before insert or update 
of department_id 
on employees 
referencing old as old_value 
new as new_value 
for each row 
说明: 
1、 无论是否规定了department_id ,对employees表进行insert的时候 
2、 对employees表的department_id列进行update的时候 
3、 触发器限制 
when (new_value.department_id<>80 ) 
限制不是必须的。此例表示如果列department_id不等于80的时候,触发器就会执行。 
其中的new_value是代表跟新之后的值。 
4、 触发操作 
是触发器的主体 
begin 
:new_value.commission_pct :=0; 
end; 
主体很简单,就是将更新后的commission_pct列置为0 
触发: 
insert into employees(employee_id, 
last_name,first_name,hire_date,job_id,email,department_id,salary,commission_pct ) 
values( 12345,‘Chen‘,‘Donny‘, sysdate, 12, ‘[email protected]‘,60,10000,.25); 
select commission_pct from employees where employee_id=12345; 
触发器不会通知用户,便改变了用户的输入值。 
触发器类型: 
1、 语句触发器 
2、 行触发器 
3、 INSTEAD OF 触发器 
4、 系统条件触发器 
5、 用户事件触发器 
1、 语句触发器 
是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器。能够与INSERT、UPDATE、 
DELETE或者组合上进行关联。但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次 
。比如,无论update多少行,也只会调用一次update语句触发器。 
例子: 
需要对在表上进行DML操作的用户进行安全检查,看是否具有合适的特权。 
Create table foo(a number); 
Create trigger biud_foo 
Before insert or update or delete 
On foo 
Begin 
If user not in (‘DONNY‘) then 
Raise_application_error(-20001, ‘You don‘t have access to modify this table.‘); 
End if; 
End; 

即使SYS,SYSTEM用户也不能修改foo表 
[试验] 
对修改表的时间、人物进行日志记录。 
1、 建立试验表 
create table employees_copy as select *from hr.employees 
2、 建立日志表 
create table employees_log( 
who varchar2(30), 
when date); 
3、 在employees_copy表上建立语句触发器,在触发器中填充employees_log 表。 
Create or replace trigger biud_employee_copy 
Before insert or update or delete 
On employees_copy 
Begin 
Insert into employees_log( 
Who,when) 
Values( user, sysdate); 
End; 

4、 测试 
update employees_copy set salary= salary*1.1; 
select *from employess_log; 
5、 确定是哪个语句起作用? 
即是INSERT/UPDATE/DELETE中的哪一个触发了触发器? 
可以在触发器中使用INSERTING / UPDATING / DELETING 条件谓词,作判断: 
begin 
if inserting then 
----- 
elsif updating then 
----- 
elsif deleting then 
------ 
end if; 
end; 
if updating(‘COL1‘) or updating(‘COL2‘) then 
------ 
end if; 
[试验] 
1、 修改日志表 
alter table employees_log 
add (action varchar2(20)); 
2、 修改触发器,以便记录语句类型。 
Create or replace trigger biud_employee_copy 
Before insert or update or delete 
On employees_copy 
Declare 
L_action employees_log.action%type; 
Begin 
if inserting then 
l_action:=‘Insert‘; 
elsif updating then 
l_action:=‘Update‘; 
elsif deleting then 
l_action:=‘Delete‘; 
else 
raise_application_error(-20001,‘You should never ever get this error.‘); 
Insert into employees_log( 
Who,action,when) 
Values( user, l_action,sysdate); 
End; 

3、 测试 
insert into employees_copy( employee_id, last_name, email, hire_date, job_id) 
values(12345,‘Chen‘,‘[email protected]‘,sysdate,12); 
select *from employees_log 
update employees_copy set salary=50000 where employee_id = 12345; 
2、 行触发器 
是指为受到影响的各个行激活的触发器,定义与语句触发器类似,有以下两个例外: 
1、 定义语句中包含FOR EACH ROW子句 
2、 在BEFORE……FOR EACH ROW触发器中,用户可以引用受到影响的行值。 
比如: 
定义: 
create trigger biufer_employees_department_id 
before insert or update 
of department_id 
on employees_copy 
referencing old as old_value 
new as new_value 
for each row 
when (new_value.department_id<>80 ) 
begin 
:new_value.commission_pct :=0; 
end; 

Referencing 子句: 
执行DML语句之前的值的默认名称是 :old ,之后的值是 :new 
insert 操作只有:new 
delete 操作只有 :old 
update 操作两者都有 
referencing子句只是将new 和old重命名为new_value和old_value,目的是避免混淆。比如操作一个名为 
new的表时。 
作用不很大。 
[试验]:为主健生成自增序列号 
drop table foo; 
create table foo(id number, data varchar2(20)); 
create sequence foo_seq; 
create or replace trigger bifer_foo_id_pk 
before insert on foo 
for each row 
begin 
select foo_seq.nextval into :new.id from dual; 
end; 

insert into foo(data) values(‘donny‘); 
insert into foo values(5,‘Chen‘); 
select * from foo; 
3、 INSTEAD OF 触发器更新视图 
Create or replace view company_phone_book as 
Select first_name||‘, ‘||last_name name, email, phone_number, 
employee_id emp_id 
From hr.employees; 
尝试更新email和name 
update hr.company_phone_book 
set name=‘Chen1, Donny1‘ 
where emp_id=100 
create or replace trigger update_name_company_phone_book 
INSTEAD OF 
Update on hr.company_phone_book 
Begin 
Update hr.employees 
Set employee_id=:new.emp_id, 
First_name=substr(:new.name, instr(:new.name,‘,‘)+2), 
last_name= substr(:new.name,1,instr(:new.name,‘,‘)-1), 
phone_number=:new.phone_number, 
email=:new.email 
where employee_id=:old.emp_id; 
end; 
4、 系统事件触发器 
系统事件:数据库启动、关闭,服务器错误 
create trigger ad_startup 
after startup 
on database 
begin 
-- do some stuff 
end; 

5、 用户事件触发器 
用户事件:用户登陆、注销,CREATE / ALTER / DROP / ANALYZE / AUDIT / GRANT / REVOKE / 
RENAME / TRUNCATE / LOGOFF 
例子:记录删除对象 
1. 日志表 
create table droped_objects( 
object_name varchar2(30), 
object_type varchar2(30), 
dropped_on date); 
2.触发器 
create or replace trigger log_drop_trigger 
before drop on donny.schema 
begin 
insert into droped_objects values( 
ora_dict_obj_name, -- 与触发器相关的函数 
ora_dict_obj_type, 
sysdate); 
end; 

3. 测试 
create table drop_me(a number); 
create view drop_me_view as select *from drop_me; 
drop view drop_me_view; 
drop table drop_me; 
select *from droped_objects 
禁用和启用触发器 
alter trigger <trigger_name> disable; 
alter trigger <trigger_name> enable; 
事务处理: 
在触发器中,不能使用commit / rollback 
因为ddl语句具有隐式的commit,所以也不允许使用 
视图: 
dba_triggers

oracle 触发器 学习笔记,布布扣,bubuko.com

时间: 2024-10-07 01:16:01

oracle 触发器 学习笔记的相关文章

Oracle Rac11g 学习笔记

查看集群节点状态 命令是olsnodes -i 显示每个节点的VIP, -n 显示每个节点在RAC集群中的编号 -p 显示每个节点所使用的私有IP地址 -s 显示每个节点的状态(activive或者inactive) 列车集群中所有资源 crs_stat -t 查看crs资源状态 crsctl check crs 查看ctss服务的状态 crsctl check ctss 查看集群中所有节点状态 crsctl check cluster -all 查看ASM实例进程 ps -ef | grep

oracle入门学习笔记

Oracle学习笔记 推荐书籍:<Oracle有用教程(从入门到精通)>.<深入浅出Oracle> 1. 当前主流数据库: |-微软:SQL Server.access |-瑞典:Mysql |-IBM: DB2 |-Sybase: Sybase |-Oracle:Oracle A. 小型数据库:access.foxbase. 负载量小,100人内,成本千元内,安全性要求不高. 比如留言板等. B. 中型数据库:Mysql.SQL Server.Informix.日訪问量5000-

Oracle触发器学习记录

1.这是oracle的规定,不能对执行触发器的表进行操作.可以对new.xxx进行操作啊,对于oracle行级触发器(for each row),不能对本表做任何操作,包括读取原则:在before insert触发器中,可以实现对本表的访问:在after insert触发器中,不能实现对本表的访问:在before/after update/delete触发器中,都不能实现对本表的访问 其实原因很简单,就是为了防止脏读2.写oracle行级触发器时,不能操作本表,报表 *** 发生了变化,触发器/

Oracle数据库学习笔记(一)

Oracle以其跨平台操作系统和硬件平台.稳定性.安全性.性能优越而著称于世.主要包括两个方向: 1).数据库管理员方向,主要学习对Oracle本身进行管理,提升性能,优化数据存储结构: 2).数据库程序员方向,在Oracle基础上对Oracle进行程序开发. PL/SQL是Oracle公司对关系型数据库的标准语言SQL的过程化语言扩展,特征包括:变量定义.控制结构.自定义的子程序.对象类型. PL/SQL程序的最基本的组成单元是PL/SQL块,分为:匿名块.命名块.命名块又可分为子程序.包.触

oracle触发器学习

转自:http://blog.csdn.net/indexman/article/details/8023740/ 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 触发器触发次序 8.2.2 创建DML触发器 8.2.3 创建替代(INSTEAD OF)触发器 8.2.3 创建系统事件触发器 8.2.4 系统触发器事件属性 8.2.5 使用触发器谓词 8.2.6 重新编译触发器 8.3 删除和使能触

oracle 触发器学习

触发器使用教程和命名规范 目  录触发器使用教程和命名规范 11,触发器简介 12,触发器示例 23,触发器语法和功能 34,例一:行级触发器之一 45,例二:行级触发器之二 46,例三:INSTEAD OF触发器 67,例四:语句级触发器之一 88,例五:语句级触发器之二 99,例六:用包封装触发器代码 1010,触发器命名规范 11 1,触发器简介触发器(Trigger)是数据库对象的一种,编码方式类似存储过程,与某张表(Table)相关联,当有DML语句对表进行操作时,可以引起触发器的执行

触发器七(复合触发器)(学习笔记)

复合触发器 复合触发器是在Oracle 11g之后引入进来的一种新结构的触发器,复合触发器既是表级触发器又是行级触发器.在之前针对于不同级别的触发器,如果要在一张数据表上完成表级触发(BEFORE和AFTER)与行级触发(BEFORE和AFTER)则需要编写四个触发器才可以完成,而有了复合触发器之后,只需要一个触发器就可以定义完全部的四个功能 使用复合触发器可以捕获四个操作事件: 触发执行语句之前(BEFORE STATEMENT) 触发语句中的每一行发生变化之前(BEFORE EACH ROW

触发器五(建立INSTEAD OF触发器)(学习笔记)

INSTEAD OF触发器 对于简单视图,可以直接执行INSERT,UPDATE和DELETE操作但是对于复杂视图,不允许直接执行INSERT,UPDATE和DELETE操作.为了在具有以上情况的复杂视图上执行DML操作需要征用触发器来完成 --创建复杂视图 CREATE OR REPLACE VIEW v_emp20 AS SELECT e.empno,e.ename,e.job,e.sal,d.deptno,d.dname,d.loc FROM emp e,dept d WHERE e.de

Oracle数据库学习笔记

创建表的同时插入数据:create table zhang3 as select * from zhang1;create table zhang3(id,name) as select * from zhang1; 将查询数据插入到某个表中:insert into zhang3 select * from zhang1;insert into zhang3(id,name) select * from zhang1; 有关完整性约束,表名,列名的两个视图:user_constraints, u