oracle触发器
oracle 触发器工作原理

oracle触发器工作原理Oracle数据库中的触发器是一种存储过程,它在特定的数据库操作(如INSERT、UPDATE或DELETE)发生时自动执行。
触发器可以用于实现数据一致性、审计、业务规则验证和复杂的数据处理逻辑。
以下是Oracle触发器工作原理的基本概述:1.定义与激活:在Oracle中,通过使用CREATE TRIGGER语句创建触发器,指定其名称、触发时机(BEFORE或AFTER)、触发事件(INSERT、UPDATE、DELETE或COMMIT等)以及作用的对象(表或视图)。
2.触发时机:BEFORE触发器会在实际操作之前执行,此时可以查看并修改将要插入、更新或删除的数据。
AFTER触发器则在实际操作完成之后执行,此时只能查看已经更改后的结果。
3.触发上下文:对于INSERT操作,触发器可以通过:NEW伪记录访问被插入的新行数据。
对于UPDATE操作,触发器同时可以获得:OLD和:NEW伪记录,分别代表更新前的老数据和更新后的新数据。
对于DELETE操作,触发器可以通过:OLD伪记录访问即将被删除的行数据。
4.执行逻辑:触发器内的PL/SQL代码会根据触发条件进行执行,可以包含任何合法的PL/SQL命令,包括对其他表的操作、控制流语句、异常处理等。
5.事务处理:触发器是事务的一部分,所以它们遵循ACID属性,并且其行为受当前事务的影响。
例如,如果事务回滚,则触发器所做的所有变更也会随之回滚。
6.实例应用:举例来说,一个AFTER INSERT触发器可能用来记录新插入数据到审计表中;而一个BEFORE UPDATE触发器可能用于检查更新的数据是否满足某些业务规则,如果不满足则阻止更新操作。
总之,Oracle触发器是数据库系统内嵌的一种自动化机制,它在特定数据库事件发生时自动执行预定义的逻辑,为确保数据完整性和业务规则得以强制执行提供了强大的支持。
Oracle 用户事件触发器

Oracle 用户事件触发器用户事件触发器是建立在模式级的操作上的触发器。
激活该类型触发器的用户事件包括:CREATE、ALTER、DROP、ANAL YZE、ASSOCIATE STATISTICS、DISASSOCIATE 、STA TISTICS、COMMENT、GRANT、REVOKE、RENAME、TRUNCA TE、LOGOFF、SUSPEND 和LOGON。
下面的示例将创建一个用户模式级触发器,以记录用户删除的数据库对象。
(1)以SCOTT身份连接到数据,并建立一个日志信息表。
SQL> create table droped_objects(2 object_name varchar2(30),3 object_type varchar2(30),4 dropped_on date);表已创建。
(2)创建用户事件触发器,以便记录用户删除的数据库对象。
SQL> create or replace trigger log_drop_trigger2 before drop on scott.schema3 begin4 insert into droped_objects values(5 ora_dict_obj_name,6 ora_dict_obj_type,7 sysdate);8 end;9 /触发器已创建在编写用户事件触发器时,经常会需要使用一些事件属性函数,例如,上面示例中的ORA_DICT_OBJ_NAME和ORA_DICT_OBJ_TYPE函数。
常用的事件属性函数如表7-1所示。
表7-1 事件属性函数事件属性函数说明ora_client_ip_address 返回客户端的IP地址ora_database_name 返回当前数据库名ora_des_encrypted_password 返回DES加密后的用户口令ora_dict_obj_name 返回DDL操作所对应的数据库对象名ora_dict_obj_name_list(name_list out ora_name_list_t) 返回在事件中被修改的对象名列表ora_dict_obj_owner 返回DDL操作所对应的对象的所有者名ora_dict_obj_owner_list(owner_list out ora_name_list_t) 返回在事件中被修改的对象的所有者列表ora_dict_obj_type 返回ddl操作所对应的数据库对象的类型ora_grantee(user_list out ora_name_list_t) 返回授权事件的授权者ora_instance_num 返回例程号ora_is_alter_column(column_name in varchar2) 检测特定列是否被修改ora_is_creating_nested_table 检测是否正在建立嵌套表ora_is_drop_column(column_name in varchar2) 检测特定列是否被删除ora_is_servererror(error_number) 检测是否返回了特定oracle错误ora_login_user 返回登录用户名ora_sysevent 返回触发器的系统事件名(3)删除SCOTT模式下的一些表或视图,测试触发器的运行情况。
Oracle触发器trigger详解

Oracle触发器trigger详解触发器相关概念及语法,供⼤家参考,具体内容如下概述本篇博⽂中主要探讨以下内容:什么是触发器触发器的应⽤场景触发器的语法触发器的类型案例数据:触发器的概念和第⼀个触发器数据库触发器是⼀个与表相关联的,存储的PL/SQL 语句。
每当⼀个特定的数据操作语句(insert update delete)在指定的表上发出时,Oracle⾃动执⾏触发器中定义的语句序列。
举个简单的例⼦:当员⼯表中新增⼀条记录后,⾃动打印“成功插⼊新员⼯”create or replace trigger insertStaffHintafter insert on xgj_testfor each rowdeclare-- local variables herebegindbms_output.put_line('新增员⼯成功');end insertStaffHint;触发器的应⽤场景复杂的安全性检查数据的确认数据库审计数据的备份和审计触发器的语法CREATE [OR REPLACE] TRIGGER trigger_name{BEFORE | AFTER }{INSERT | DELETE | UPDATE [OF column [, column …]]}[OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...]ON [schema.]table_name | [schema.]view_name[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}][FOR EACH ROW ][WHEN condition]PL/SQL_BLOCK | CALL procedure_name;其中:BEFORE 和AFTER指出触发器的触发时序分别为前触发和后触发⽅式,前触发是在执⾏触发事件之前触发当前所创建的触发器,后触发是在执⾏触发事件之后触发当前所创建的触发器。
oracle触发器的实例(转)

oracle触发器的实例(转)触发器使⽤教程和命名规范⽬录触发器使⽤教程和命名规范 11,触发器简介 12,触发器⽰例 23,触发器语法和功能 34,例⼀:⾏级触发器之⼀ 45,例⼆:⾏级触发器之⼆ 46,例三:INSTEAD OF触发器 67,例四:语句级触发器之⼀ 88,例五:语句级触发器之⼆ 99,例六:⽤包封装触发器代码 1010,触发器命名规范 111,触发器简介触发器(Trigger)是数据库对象的⼀种,编码⽅式类似存储过程,与某张表(Table)相关联,当有DML语句对表进⾏操作时,可以引起触发器的执⾏,达到对插⼊记录⼀致性,正确性和规范性控制的⽬的。
在当年C/S时代盛⾏的时候,由于客户端直接连接数据库,能保证数据库⼀致性的只有数据库本⾝,此时主键(Primary Key),外键(Foreign Key),约束(Constraint)和触发器成为必要的控制机制。
⽽触发器的实现⽐较灵活,可编程性强,⾃然成为了最流⾏的控制机制。
到了B/S时代,发展成4层架构,客户端不再能直接访问数据库,只有中间件才可以访问数据库。
要控制数据库的⼀致性,既可以在中间件⾥控制,也可以在数据库端控制。
很多的青睐Java的开发者,随之将数据库当成⼀个⿊盒,把⼤多数的数据控制⼯作放在了Servlet中执⾏。
这样做,不需要了解太多的数据库知识,也减少了数据库编程的复杂性,但同时增加了Servlet编程的⼯作量。
从架构设计来看,中间件的功能是检查业务正确性和执⾏业务逻辑,如果把数据的⼀致性检查放到中间件去做,需要在所有涉及到数据写⼊的地⽅进⾏数据⼀致性检查。
由于数据库访问相对于中间件来说是远程调⽤,要编写统⼀的数据⼀致性检查代码并⾮易事,⼀般采⽤在多个地⽅的增加类似的检查步骤。
⼀旦⼀致性检查过程发⽣调整,势必导致多个地⽅的修改,不仅增加⼯作量,⽽且⽆法保证每个检查步骤的正确性。
触发器的应⽤,应该放在关键的,多⽅发起的,⾼频访问的数据表上,过多使⽤触发器,会增加数据库负担,降低数据库性能。
oracle异常及触发器

–
values (‘another error occurred’);
– end;
– *sqlcode和sqlerrm先被赋值给本地变量,然后这些变量在sql语句中被使 用,sqlcode和sqlerrm不能直接在sql语句中使用,因为他们是过程性的 函数。sqlcode返回当前的错误号,sqlerrm返回当前的错误信息正文。
oracle 异常及触发器
0
异常处理
什么是异常情态
– 异常处理处理的是运行时错误,异常分为预定义异常和用户自定义 异常。
– 声明异常情态
– 异常情态在块的声明部分进行声明,在块的执行部分进行触发,在 块的异常部分进行处理。
用户定义类型异常情态,需要程序员自己定义代码,对异常情况进 行处理。
– 例: – Declare – e_toomanystudents exception;
– Pragma必须在声明部分
– 例:下面的例子在运行时刻如遇到“ora-1400:mandatory not
– null column missing or null during insert” 错 误 时 , 将 引 发 e_missingnull异常情态。
– Declare
– e_missingnull exception;
–
–
7
代码 消息
0 ora-0000:normal,successful completion
+10 Ora-1403:no data found 0
+10 User-defined exception
null -1
8 -54
ora-0000:normal,successful completion
oracle触发器-解决mutating table的问题

Oracle触发器mutating table问题解决方案一、问题描述Oracle触发器是特定事件出现的时候,自动执行的代码块。
但在使用过程中,往往遇到如下需求:1、在触发器执行时,使用DML语言操作触发器的基础表,完成更新、插入或删除操作;2、触发器对于父子表,即有外键关联的表的相关操作;或者说trigger访问了自身上的表。
在以上两种情况下,依据Oracle的事务处理规则,通常产生如下错误:ORA-04091。
该错误解释为:当前的trigger下的事物,access(执行)了一个mutating table(冲突的表)。
一个简单的例子拿oracle的示例表emp和dept来做这个试验。
dept的表结构如下:emp表结构如下:emp和dept是一对父子表,关联column为DEPTNO。
接下来创建1个table:emp_log 和1个语句级trigger: emp_del_trg。
取一个最简单的业务功能,emp_del_trg的作用就是当表emp记录被删除的时候,触发器将删除的记录的EMPNO,DNAME和删除时间写入到emp_log中,当子表依赖的父表相关记录删除的时候,emp_log不做处理。
表emp_log的结构如下:触发器trigger代码如下:来看看这个触发器是否能正常工作,首先删除emp的记录。
看似trigger工作正常,删除dept的记录呢?问题分析:ORA-04091错误如约而至。
不难解释,因为父子表指定了级联删除,删除dept的记录从而引起删除emp表上的相应数据,然后触发了emp_del_trg,由于trigger里有对dept的访问,对当前事务说,dept就是一个mutating table,这是不被允许的。
如何来解决这个问题而实现这个简单的业务逻辑功能呢?当然,从表结构逻辑设计上来讲,可以将dept表上的dname字段add到emp表,或者不要显式的指定references,用程序来维护数据的完整性和约束,然后调整业务代码.最直接的方法,在trigger中声明一个ora-04091的exception,对此异常不做处理,也可完成目的。
oracle 触发器(trigger)

触发器的使用1触发器资料来源:《/view/71791.htm?fr=ala0_1_1》触发器(trigger)是个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作(insert,delete,update)时就会激活它执行。
触发器经常用于加强数据的完整性约束和业务规则等。
触发器可以从DBA_TRIGG ERS ,USER_TRIGGERS 数据字典中查到。
1.1 数据库领域名词触发器可以查询其他表,而且可以包含复杂的SQL语句。
它们主要用于强制服从复杂的业务规则或要求。
例如:您可以根据客户当前的帐户状态,控制是否允许插入新订单。
触发器也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。
然而,强制引用完整性的最好方法是在相关表中定义主键和外键约束。
如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。
1.2 创建触发器的SQL语法DELIMITER |CREATE TRIGGER `<databaseName>`.`<triggerName>`< [ BEFORE | AFTER ] > < [ INSERT | UPDATE | DELETE ] >ON <tableName>FOR EACH ROWBEGIN--do somethingEND |1.3 触发器的优点触发器可通过数据库中的相关表实现级联更改;不过,通过级联引用完整性约束可以更有效地执行这些更改。
触发器可以强制比用CHECK 约束定义的约束更为复杂的约束。
与CHECK 约束不同,触发器可以引用其它表中的列。
例如,触发器可以使用另一个表中的SELECT 比较插入或更新的数据,以及执行其它操作,如修改数据或显示用户定义错误信息。
触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。
Oracle触发器基础教程

Oracle触发器基础教程Oracle触发器是一种特殊的数据库对象,它是一段由PL/SQL或Java编写的代码,当指定的条件满足时,会自动地在数据库中执行。
Oracle触发器可以在插入、更新或删除数据时触发一系列的动作,从而实现对数据的自动控制和处理。
一、创建触发器在Oracle中,使用CREATE TRIGGER语句可以创建触发器。
语法如下:CREATE [OR REPLACE] TRIGGER trigger_name{BEFORE,AFTER,INSTEADOF}{INSERT,UPDATE,DELETE}[OR {INSERT , UPDATE , DELETE} OF column_name][ON table_name][REFERENCING OLD AS old NEW AS new][FOREACH{ROW,STATEMENT}][WHEN (condition)][DECLARE]--声明变量和游标BEGIN--触发器代码--新增、修改或删除数据的动作END;trigger_name:触发器的名称,必须唯一BEFORE、AFTER、INSTEADOF:触发器执行的时间,BEFORE表示在数据操作之前执行,AFTER表示在数据操作之后执行。
INSERT、UPDATE、DELETE:触发器执行的操作类型,可以是插入、更新或删除。
column_name:触发器监听的列名。
table_name:触发器所在的表名。
REFERENCING:指定触发器中使用的旧值和新值的别名,可以在触发器代码中使用。
FOREACH:指定触发器是对每一行执行还是每条语句执行。
WHEN:指定触发器执行的条件。
二、触发器的类型1.行级触发器(FOREACHROW)行级触发器是对每一行进行操作的触发器,它会在每一行插入、更新或删除之后触发。
这种触发器常用于数据的验证和约束条件的实现。
2.语句级触发器(FOREACHSTATEMENT)语句级触发器是对每条语句进行操作的触发器,它会在数据操作语句执行完成后触发。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
伯触发器是特定事件出现的时候,自动执行的代码块。
类似于存储过程,但是用户不能直接调用他们。
功能:1、允许/限制对表的修改2、自动生成派生列,比如自增字段3、强制数据一致性4、提供审计和日志记录5、防止无效的事务处理6、启用复杂的业务逻辑开始create trigger biufer_employees_department_idbefore insert or updateof department_idon employeesreferencing old as old_valuenew as new_valuefor each rowwhen (new_value.department_id<>80 )begin:new_mission_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 updateof department_idon employeesreferencing old as old_valuenew as new_valuefor 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_mission_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,‘donny@’,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_fooBefore insert or update or deleteOn fooBeginIf user not in (‘DONNY’) thenRaise_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 *fromhr.employees2、建立日志表create table employees_log(who varchar2(30),when date);3、在employees_copy表上建立语句触发器,在触发器中填充employees_log 表。
Create or replace trigger biud_employee_copyBefore insert or update or deleteOn employees_copyBeginInsert 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 条件谓词,作判断:beginif inserting then-----elsif updating then-----elsif deleting then------end if;end;if updating(‘COL1’) or updating(‘COL2’) then------end if;[试验]1、修改日志表alter table employees_logadd (action varchar2(20));2、修改触发器,以便记录语句类型。
Create or replace trigger biud_employee_copyBefore insert or update or deleteOn employees_copyDeclareL_action employees_log.action%type;Beginif inserting thenl_action:=’Insert’;elsif updating thenl_action:=’Update’;elsif deleting thenl_action:=’Delete’;elseraise_application_error(-20001,’Y ou 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’,’Donny@hotmail’,sy sdate,12);select *from employees_logupdate employees_copy set salary=50000 where employee_id = 12345;2、行触发器是指为受到影响的各个行激活的触发器,定义与语句触发器类似,有以下两个例外:1、定义语句中包含FOR EACH ROW子句2、在BEFORE……FOR EACH ROW触发器中,用户可以引用受到影响的行值。
比如:定义:create trigger biufer_employees_department_idbefore insert or updateof department_idon employees_copyreferencing old as old_valuenew as new_valuefor each rowwhen (new_value.department_id<>80 )begin:new_mission_pct :=0;end;/Referencing 子句:执行DML语句之前的值的默认名称是:old ,之后的值是:new insert 操作只有:newdelete 操作只有:oldupdate 操作两者都有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_pkbefore insert on foofor each rowbeginselect 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_idFrom hr.employees;尝试更新email和nameupdate pany_phone_bookset name=’Chen1, Donny1’where emp_id=100create or replace triggerupdate_name_company_phone_bookINSTEAD OFUpdate on pany_phone_bookBeginUpdate hr.employeesSet employee_id=:new.emp_id,First_name=substr(:, instr(:,’,’)+2), last_name= substr(:,1,instr(:,’,’)-1), phone_number=:new.phone_number,email=:new.emailwhere employee_id=:old.emp_id;end;4、系统事件触发器系统事件:数据库启动、关闭,服务器错误create trigger ad_startupafter startupon databasebegin-- do some stuffend;/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_triggerbefore drop on donny.schemabegininsert 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触发器语法触发器是特定事件出现的时候,自动执行的代码块。