大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说触发器 trigger[亲测有效],希望您对编程的造诣更进一步.
触发器是被指定关联到一个表的数据对象,它不需要调用,当对一个表的特别事件出现时,它就被激活。触发器的代码也是由SQL语句组成的,因此用在存储过程中的语句也可以用再触发器的定义中。触发器是一类特殊的存储过程,与表的关系密切,用于保护表中的数据,当有操作影响到触发器保护的数据时,触发器将自动执行。
(1)DML触发器:当数据库中发生数据操作语句(DML)事件时调用DML触发器。DML事件包括用表或视图的 insert语句,update语句和delect语句,因此DML触发器可分为3种。
(2)代替触发器:由于oracle中不能直接对两个以上的表建立的视图进行操作,所以给出了代替触发器。它是oracle专门为进行视图操作的一种处理方式。
(3)系统触发器:系统触发器也由相应的事件触发,但它的激活一般基于对数据库系统所进行得操作,如数据定义语句(DDL),启动或关闭触发器,连接或断开,服务器错误等系统事件。
命令创建触发器:
--语法格式 create or replace trigger 触发器的名称 before /after/instead of insert/update/delete on for each row
代码100分
说明:
触发器名称:触发器的名字与过程名和包的名字不一样,它有单独的名字空间,因此触发器名可以和表名或过程名同名,但在同一个方案中的触发器名不能相同。
after:触发器在指定操纵都成功执行后触发,如after insert 表示在向表中插入数据后激活触发器
before:触发器在指定操作执行前触发,如before insert 表示在向表中插入数据前激活触发器
instead of: 指定创建代替触发器,触发器指定的事件不执行,而执行触发器本身的操作。
delete,insert,update:指定一个或多个触发器,多个触发器事件之间用 or 连接
of:指定在某列上update触发器,如果为多列,则需要使用逗号分隔。
for each row:在触发器定义中,如果未使用for each row 子句则表示触发器为语句触发器,触发器在激活后只执行一次,而不管这一操作将影响多行。
创建触发器有以下限制:
(1) 代码大小。触发器代码大小必须小于32K。
(2) 触发器中有效语句可以包括DML语句,但不能包括DDL语句。ROLLBACK、COMMIT、SAVEPOINT也不能使用。但是,对于系统触发器(system trigger)可以使用CREATE、ALTER、DROP TABLE和ALTER…COMPILE语句。
(3) LONG、LONG RAW和LOB的限制:
① 不能插入数据到LONG或LONG RAW;
② 来自LONG或LONG RAW的数据可以转换成字符型(如char、varchar2),但是不能超过32K;
③ 使用LONG或LONG RAW不能声明变量;
④ 在LONG或LONG RAW列中不能使用:NEW和:PARENT;
⑤ 在LOB中的:NEW变量不能修改。
(4) 引用包变量的限制。如果UPDATE或DELETE语句检测到当前的UPDATE冲突,则Oracle执行ROLLBACK到SAVEPOINT上并重新启动更新,这样可能需要多次才能成功。
创建DML触发器:
代码100分--假设数据库中增加一新表school_students_old,表结构和表school_students相同,用来存放从school_students表 --中删除的记录。创建一个触发器,当school_students表被删除一行,把删除的记录写到日志表school_students_old中。
create table school_students_old2 //创建新表 ( STU_ID NVARCHAR2(20) NOT NULL, STU_NAME NVARCHAR2(20) NOT NULL , STU_SEX NVARCHAR2(20) , STU_CREDITS NUMBER(2) , STU_BIRTHDAY DATE , STU_CLASS NVARCHAR2(20) ); select * from school_students_old2; create or replace trigger delete_stu //创建触发器 before delete on school_students for each row begin insert into school_students_old2 (STU_ID,STU_NAME,STU_SEX,STU_CREDITS,STU_BIRTHDAY,STU_CLASS) values (:old.STU_ID,:old.STU_NAME,:old.STU_SEX,:old.STU_CREDITS,:old.STU_BIRTHDAY,:old.STU_CLASS); end delete_stu; select * from school_students; select * from school_students_old;
创建代替触发器:
--在数据库中创建视图和触发器,以说明替代触发器。 create or replace view stu_avg as select RESULT_STU, avg(result_number) as stu_avg from SCHOOL_RESULT group by RESULT_STU; select * from stu_avg where RESULT_STU="201632218031"; delete from stu_avg where RESULT_STU="201632218031"; create or replace trigger tr_stu_avg_delete instead of delete on stu_avg for each row begin delete from SCHOOL_RESULT where result_stu=:old.result_stu; end tr_stu_avg_delete;
创建系统触发器:
代码100分--创建当一个用户userA登录时自动记录一些信息的触发器。 create table login_log ( v_user varchar2(100), v_date date ); create or replace trigger tr_login_log after logon on schema declare v_name VARCHAR2(20); begin select user into v_name from dual; insert into login_log values(v_name,sysdate); end tr_login_log; select * from login_log;
启用和禁用触发器:
在oracle中,与过程,函数,包不同,触发器是可以被禁用和启用的,在有大量数据要导入数据库中时,为了避免触发相应的触发器以节省处理时间,可以禁用触发器,使其暂时失效,触发器被禁用后任然存储在数据库中,只要重新启用既可以使它重新工作。
oracle提供了alter trigger语句来禁用和启用触发器
--语法格式 alter trigger [<用户名方案名.>]<触发器> disable|enable;
其中:disable表示禁用触发器,enable表示启用触发器
触发器的删除:
--语法格式
drop trigger [<用户名方案名.>]<触发器>
也可以用界面删除触发器
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/7700.html