触发器的定义
触发器定义就是当某个条件成立的时候,触发器里面定义的语句就会自动被执行,因此触发器不需要人为的去调用,也不能调用,并且触发器的触发条件其实是在你定义的时候就已经设定好了。
触发器分类
触发器分为两种
1. 语句级触发器:可以在某些语句执行前或执行后被触发
2. 行级触发器:在定义的触发的表中的行数据改变时就会被触发一次
触发器的语法
1. 触发器名:触发器对象的名称。由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。
2. 触发时间:指明触发器何时执行,该值可取(before和after,其中before是表示在数据库动作之前触发器执行,after表示在数据库动作之后触发器执行)。
3. 触发事件:指明哪些数据库动作会触发此触发器(insert update delete)。
4. 表名:数据库触发器所在的表。
5. for each row:对表的每一行触发器执行一次。如果没有这一选项,则只对整个表执行一次
1 create [or replace] tigger 触发器名 触发时间 触发事件 2 on 表名 3 [for each row] 4 begin 5 pl/sql语句 6 end
触发器能实现的功能
1. 允许/限制对表的修改
2. 自动生成派生列,比如自增字段
3. 强制数据一致性
4. 提供审计和日志记录
5. 防止无效的事务处理
6. 启用复杂的业务逻辑
触发器的删除
drop trigger trigger_name //其中trigger_name为触发器的名称
触发器的创建(pl/sql)
首先我们在数据库中创建一个表,用于练习。
之后打开plsql软件连上数据库,之后在左侧文件夹中找到triggers文件夹点击右键--新建,如图:
1. name:触发器的名字,根据要求起一个就可以。
2. fires:分为三种before,after,instead of
3. event:分为三种update,delete,insert
4. table or view:表名或视图名
注意:
1. trigger为触发器的标志。
2. before代表对表执行操作表之前触发。
3. 表名前面要加on关键字。
4. 此段代码的意思是不让周一操作表。
create or replace trigger test1 before insert on t_user--对表的添加操作 create or replace trigger test1 before insert or update or delete on t_user--对表的添加/修改/删除操作 begin if(to_char(sysdate,'DY') = '星期一') then raise_application_error(-20600,'不能在周一操作表t_user'); end if; end test1;
如果对表执行了操作动作,会提示以下信息。
触发器的应用
问题:使用触发器实现序号自增。此功能非常的常见,需要使用序列+触发器来共同实现,如果不了解序列的小伙伴百度一下就可以了。另外要说一下,mysql可以设置主键自增,就不用这么麻烦了。
1. 首先在创建表的时候在id列上加上主键,如果表已经创建好了,也可以通过语句后加上 alter table t_user add constraint PK_ID primary key (id);
2. 之后创建一个序列,注意创建序列的时候要保证数据的唯一性 id不允许重复,否则会报错。
create sequence my_seq increment by 1 start with 1 nomaxvalue nocycle cache 20;或者
create sequence my_seq minvalue 1 maxvalue 99 start with 1 increment by 1 nocache;
my_seq:序列名
increment by 1:每次加1个
start with 1: 从1开始
nomaxvalue: 不设置最大值
nocycle: 一直累加,不循环
cache 20: 设置缓存cache个序列,如果系统down掉了或者其它情况将会导致序列不连续,也可以设置为---------NOCACHE
之后 使用insert into t_user (id,name) values (my_seq.Nextval,'李四')就可以实现自增了,但是能不能在insert的时候不用填入id实现自增呢?这里我们通过创建一个触发器就可以实现了。
1 create or replace trigger test2 before insert on t_user for each row 2 declare 3 nextid number; 4 begin 5 if :new.id is null or :new.id=0 then 6 select my_seq.nextval into nextid from sys.dual; 7 :new.id:=nextid;--:new表示新插入的那条记录 8 end if; 9 end test2;
之后 执行insert into t_user (name) values ('张三') 可以看到数据正常自增并被添加进入了
持续更新!