触发器的基本概念
触发器是指隐含执行的存储过程。是特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。
触发器的语法:
createorreplacetriggertrigger_name
after/before
insertorupdateordelete
ontable_name
referencingoldasold_valuenewasnew_value
foreachrow/foreachstatement
begin
代码块;
end;
语法解析:
1、createorreplace创建一个触发器。Replace表示当触发器存在相同的触发器时,替换掉已存在的触发器。
2、after/before表示触发时机。事件之前执行还是事件之后执行。
3、insert/update/delete触发器监控的事件
4、ontable_name触发器监控的表:table_name
5、foreachrow行触发器。每操作一行就触发一次
foreachstatement语句触发器。针对指定语句激活一次。
6、referencing设置参照变量,as表示作为。old_value,new_value行变量。分别表示事件发生前/后的数据所在的行。即old_value表示操作前的数据,new_value表示操作后的数据。可以用old_value.字段名、new_value.字段名,调用相应的字段。触发器的功能
允许/对表的操作自动生成派生列,例如自增字段强制数据一致性提供审计和日志管理防止无效的事务处理启用复杂的业务逻辑
触发器的组成
1、触发器名称
2、触发语句
3、触发器
4、触发操作
Instance:
createtriggerbiufer_employees_department_id
beforeinsertorupdateofdepartment_id
onemployees
referencingoldasold_valuenewasnew_valueforeachrow
when(XXX<>80)
begin
:XXX:=0;
end;
1、触发器名称:createtriggertrigger_name
2、触发语句:
before/afterinsertorupdateof[ColumnsName||department_id]
on[TableName||employees]
referencingoldasold_valuenewasnew_value
foreachrow
说明:1、表或视图上的DML语句DDL语句数据库关闭或启动,startupshutdown等等
2、无论是否规定了department_id,对employees表进行insert的时候都会触发
3、对employees表的department_id列进行update的时候也会触发触发器。
3、触发器:
when(XXX<>80)不是必须的。此例表示如果列department_id不等于80的时候,触发器就会执行。
其中的new_value是代表跟新之后的值。
4、触发操作
触发操作是触发器的主体。
begin
:XXX:=0;
end;
这里主体表示的是将更新后的commission_pct设置为0
5、触发
insertintoemployees(
employee_id,last_name,first_name,hire_date,job_id,email,department_id,salary,
commission_pct)
values(12345,’chen’,’Donny’,syadate,12,‘’,60,10000,.25);
selectcommission_pctfromemployeeswhereemployee_id=12345;
触发器在不通知用户的情况下,已经对用户输入的数据值进行修改。
触发器的类型
1、语句触发器
2、行触发器
3、insteadof触发器
4、用户事件触发器
5、系统事件触发器
各种触发器的详解:
1、语句触发器:语句触发器是在表上或者某些情况下的视图上执行的特定语句或者语
句组上的触发器。能够与insert、update、delete或者组合上进行关联。
但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次。比如,无论update多少行,也只会调用一次update语句触发器。
E_ampleOne:1、创建一个实验表
createtablee_ample_trigger_student(
stu_nonumber(6),
stu_namevarchar2(20),
stu_agenumber(3),
stu_se_varchar2(10)
2、创建一个自增序列createsequencee_ample_trigger_stu;
3、创建触发器。触发器名称为biud_student1
createorreplacetriggerbiud_student1
beforeinsertorupdateordeleteone_ample_trigger_studentbegin
--区分大小写。hby与HBY
--ifusernotin('hby')then
ifusernotin('HBY')then
--raise_application_error固定语句
raise_application_error(-20001,'youdonthavaaccesstomodifythistable');
endif;
end;
4、插入数据,触发
insertintoe_ample_trigger_student
values(XXX,'Dan',24,'male');
5、查询表里面的内容
selectfrome_ample_trigger_student;
E_ampleTwo:
1、记录用户时间和用户
createtablee_ample_trigger_student_logs(
stu_uservarchar2(20),
modify_timedate
2、创建触发器,将年龄修改为20
createorreplacetriggerbiud_student2
beforeinsertorupdateordeleteone_ample_trigger_student
begin
insertintoe_ample_trigger_student_logsvalues(user,sysdate);end;
3、插入数据
insertintoe_ample_trigger_student
values(XXX,'Nate',24,'male');
insertintoe_ample_trigger_student_logsvalues('Lily',sysdate);selectfrome_ample_trigger_student_logs;
2、行触发器:是指为受到影响的各个行激活的触发器,定义与语句触发器类似,有以
下两个例外:1、定义语句中包含FOREACHROW子句2、在BEFORE……FOREACHROW触发器中,用户可以引用受到影响的行值。
E_ampleOne:1、创建触发器
createtriggerbiu_student
beforeinsertorupdateone_ample_trigger_student
referencingoldasold_valuenewasnew_value
--当foreachrow与when语句交换位置,会显示:when子句不能和表层触发器一起使用。foreachrow
when(XXX<>20)
begin
:XXX:=20;
end;
E_ampleTwo:1、创建表
createtablefoo(
idnumber,
f_datavarchar2(20)
2、创建自增序列
createsequencefoo_seq;
3、创建触发器
createorreplacetriggerbifer_foo_id_pk
beforeinsertonfoo
foreachrow
begin
--在冒号和new之间不能有空格。
XXX:XXX;
end;
4、插入数据,触发
insertintofoo(f_data)values('donny');
insertintofoovalues(5,'Chen');
说明:1、referencing子句执行DML语句之前默认值为old,之后为new
insert操作只有new
delete操作只有oldupdate操作old与new都具备2、DDL:数据定义语言DML:数据操作语言
3、DUAL:diffusingupdatealgorithm弥散更新算法。Dual是le与数据字典一起自动创建的一个虚拟表。只有一列:dummy。其数据类型为varchar2(1)。
Dual只有一行数据:‘_’,属于sys模式。所有的用户都可以使用dual名称访问。Dual主要用来查询不属于实际表里面的内容。有时也用来检查某表某条件的记录存在性。
3、insteadof触发器:更新视图。
Insteadof触发器的主要优点是:使不能更新的视图支持更新。基于多个表的视图
必须使用。
Insteadof触发器支持多个表中数据的插入、更新和删除。但是不能在带有with
checkoption定义的视图中创建insteadof触发器。E_ample:
--insteadof多表之间的操作
1、创建表
createtablee_ample_stu(
stu_nonumber(6),
stu_namevarchar2(20)
createtablee_ample_cou(
s_nonumber(6),
gradenumber(4,1)
2、创建视图。
XXX,stu_name,gradefrome_ample_stu,e_ample_cou;
--插入下面的语句,会显示无法修改与非建值保存列对应的表。直接插入数据时,由于是基于两张表创建的,执行时会产生错误。
--insertintosc_viewvalues(5,'Lily',85);
3、创建触发器
createtriggerinofi_sc_view
insteadofinsertonsc_view
begin
insertintoe_ample_stuvalues(:XXX,:XXX);
--stu_no是视图中的。并不是表中的e_ample_cou
insertintoe_ample_couvalues(:XXX,:XXX);
end;
4、插入数据
insertintosc_viewvalues(5,'Lily',85);
说明:1、insteadof是一种单独的触发机制。用来管理和执行view类型的数据表单
2、Ofon监控关键字。Of可以省略。On必须保留。
3、每一个表和视图只能有一个insteadof触发器。
4、用户事件触发器:又叫DDL事件触发器。
用户事件:用户登陆、注销,create/alter/drop/analyze/audit/grant/remoke/rename/truncate/logoffE_ample:
--禁止用create、drop。alter、truncate命令操作hby对象
createorreplacetriggertest_no_ddl
--如果是XXX会显示表或视图不存在,XXX则显示权限不足XXX表示的是用户hby对象的结果
XXX
begin
raise_application_error(-20001,'不允许用DDL操作hby用户的对象!');end;
--为了确保其他触发器能够运行,多数情况下,用户事件触发器需要禁止运行。
altertriggertest_no_ddldisable;
altertrigger
altertrigger
5、系统事件触发器:用来监控数据库什么时候打开,什么时候关闭。或用户logon/logoff
数据库的情况。
系统事件:数据库启动、关闭,服务器错误
系统事件触发器的语法为:
createorreplacetriggertrigger_name
before|afterstartup|shutdown|logon|logoff
ondatabase这里的on作用的一定是database,而不是其他用户。
E_ample:
--记录数据库的关闭时间。startup用关键字after,shutdown用关键字before--创建一个表存放关闭时间
createtabletime_record(
tt_timevarchar2(50)
--创建触发器
createorreplacetriggerdb_shutdown
--会显示权限不足
beforeshutdownondatabase
begin
insertintotime_record
values('dbshutdown'||tochar(sysdate,'yyyy-MM-ddhh:mm:ss'));end;
触发器总结
在触发器中,不能使用commit/rollback因为ddl语句具有隐式的commit,所以也不允许使用。
下载本文