在Oracle中,关于触发器的描述,错误的是?
A 触发器可以用来强制实现复杂的业务规则
B 触发器不能在视图上创建
C 触发器可以在DML操作之前或之后自动执行
D 触发器可以在表级别或行级别触发
注意,这道题问的是错误的是哪个,正确答案应该是选择 B。
在Oracle数据库中,视图(View)本身不能直接创建触发器。触发器(Trigger)是数据库中的一种特殊类型的存储过程,它会在指定的数据库表上执行DML(数据操纵语言)操作(如INSERT、UPDATE、DELETE)时自动执行。由于视图是基于SQL查询的虚拟表,它不存储数据,而是每次查询时动态生成数据,因此不能直接在视图上定义触发器。
然而,如果需要在某个视图的数据发生变化时执行某些操作,你可以考虑以下几种替代方案:
在基础表上创建触发器:由于视图是基于一个或多个基础表构建的,可以在构成视图的基础表上创建触发器。这样,当基础表的数据发生变化时,触发器会触发并执行相应的操作。
使用INSTEAD OF触发器:对于可更新的视图(即那些可以直接通过INSERT、UPDATE、DELETE语句更新的视图),可以在视图上定义INSTEAD OF触发器。INSTEAD OF触发器会在尝试对视图执行DML操作时触发,而不是在基础表上。这允许你定义在视图上执行DML操作时应该发生的逻辑,而不是直接在基础表上执行。
例如,如果有一个由两个表联合查询得到的视图,并且你想通过该视图更新数据,可以在该视图上定义一个INSTEAD OF UPDATE触发器,以在尝试更新视图时执行自定义的逻辑来更新基础表。
使用物化视图:如果需求是定期更新视图中的数据,并希望在这些数据更新时执行某些操作,可以考虑使用物化视图。物化视图是物理存储的,可以像表一样查询,并且可以定义在物化视图上刷新时触发的触发器。
综上所述,虽然不能直接在视图上创建触发器,但你可以通过其他方式(如在基础表上创建触发器、使用INSTEAD OF触发器、或使用物化视图)来实现类似的功能。
1.触发器
对数据库对象的操作会引发很多事件,比如before insert,before update等,当这些事件发生的时候我们可以写相应代码来完成一些基于事件的操作,
比如当在修改A表数据的时候我们可以写一个触发器来在b表中插入数据。
类型:
row级,sql语句影响到的每一行都会引发trigger
statement级,一句sql语句引发一场,不管它影响多少行(甚至0行)
当省略for each row 时,before和after为语句触发器,instead of为行触发器
多事件触发执行顺序:deleting--inserting--updating
触发事件:insert update delete
触发时间:before after
:new 修饰符访问操作完成后列的值
:old 修饰符访问操作完成前列的值
instead of:只能对视图和对象视图建立instead of触发器,不能对表、模式和数据库
互换trigger的两种状态:有效状态 无效状态
alter trigger trigger_name [disable/enable]
alter table table_name [disable/enable] all trigger 一次改变相关表的所有触发器
触发器的优缺点:
优点:
1. 自动执行。触发器在对表的数据作了任何修改(比如手工输入或者应用程序的操作)之后立即被激活。
2. 跟踪变化。触发器可以阻止数据库中未经许可的指定更新和变化。
---对表字段控制,个性化,验证等
缺点:
1、如果触发频率高,占用内存,降低数据访问速度
2、相对不灵活,一旦触发马上执行,不能排除特殊情况
3、触发器会使编程时源码的结构被迫打乱,为将来的程序修改、源码阅读带来很大不便
---维护不方便,性能
2.创建触发器
create or replace trigger trigger_name
before insert or update or delete on employees--创建触发器。当向表student中插入、修改或删除时触发
declare
action varchar2(10); --声明变量。保存操作的类型
begin
if inserting then --当执行插入操作时,inserting为true
action := ‘插入’;
elsif updating then --当执行修改操作时,updating 为true
action := ‘修改’;
elsif deleting then --当执行删除操作时,deleting 为true
action := ‘删除’;
end if;
insert into stu_log (action, shijian) values (action, sysdate);
end;
/
3.创建instead of触发器
对"视图"进行操作时定义的触发器,instead of触发器只能定义在"视图"上语法:
create [or replace] trigger trigger_name --触发器名称
instead of trigger_event --触发事件
on view_name --视图名称
for each row --替代触发器必须指定为行级的触发器
[when trigger_condition] --触发条件
trigger_body --触发体,PL/SQL块
end trigger_name;
例如:创建触发器,当删除只读视图中的数据时,employees表中原来的数据也被删除
1)首先创建视图view。需要管理员权限
create or replace view v_employees as select * from employees
with read only;
2)创建替代触发器
create or replace trigger em_instand_tri
instead of delete on v_employees
for each row
begin
delete from employees where id = :old.id;
end em_instand_tri;
/
提示::old.id是表示当前行id列的原始值




