`
sbpya
  • 浏览: 610017 次
  • 性别: Icon_minigender_1
  • 来自: 杭州,长沙
社区版块
存档分类
最新评论

Oracle中触发器的应用

阅读更多

触发器是指存放在数据库中,并且被隐含执行的存储过程。当发生特定事件时,Oracle会自动执行触发器的响应代码。

 

触发器的种类可划分为4种:1.数据操纵语言(DML)触发器、2.替代(INSTEAD OF)触发器、3.数据定义语言(DDL)触发器、4.数据库事件触发器。

 

数据操纵语言(DML)触发器:简称DML触发器,是定义在表上的触发器,创建在表上。

由DML事件引发的触发器,编写DML触发器时的两点要素是:

1.确定触发的表,即在其上定义触发器的表。

2.确定触发的事件,DML触发器的触发事件有INSERT、UPDATE和DELETE三种;替代触发器,简称INSTEAD OF触发器,创建在视图上,用来替换对视图进行的删除、插入和修改操作; 数据定义语言(DDL)触发器,简称DDL触发器,定义在模式上,触发事件是数据对象的创建和修改;数据库事件触发器,定义在整个数据库或模式上,触发事件是数据库事件.

 

功能:
1、 允许/限制对表的修改
2、 自动生成派生列,比如自增字段
3、 强制数据一致性
4、 提供审计和日志记录
5、 防止无效的事务处理
6、 启用复杂的业务逻辑

 

ORACLE产生数据库触发器的语法为:

  CREATE [OR REPLACE] TRIGGER 触发器名

 

  {BEFORE|AFTER|INSTEAD OF} 触发事件1 [OR 触发事件2...]

 

  ON 表名

 

  WHEN 触发条件

 

  [FOR EACH ROW]

 

  DECLARE

 

  声明部分

 

  BEGIN

 

  主体部分

 

  END;
###StudyGet_Info_Pagination_SIGN###
    其中:

 

  触发器名:触发器对象的名称。由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。一个触发器可由多个不同的数据操纵语言操作触发。在触发器中,可用INSERTING、DELETING、UPDATING谓词来区别不同的数据操纵语言操作。这些谓词可以在IF分支条件语句中作为判断条件来使用。

 

  触发时间:指明触发器何时执行,该值可取, 触发的时间有BEFORE和AFTER两种,分别表示触发动作发生在DML语句执行之前和语句执行之后。确定触发级别,有语句级触发器和行级触发器两种。语句级触发器表示SQL语句只触发一次触发器,行级触发器表示SQL语句影响的每一行都要触发一次。

 

  Before:表示在数据库动作之前触发器执行;在SQL语句的执行过程中,如果存在行级BEFORE触发器,则SQL语句在对每一行操作之前,都要先执行一次行级BEFORE触发器,然后才对行进行操作。如果存在行级AFTER触发器,则SQL语句在对每一行操作之后,都要再执行一次行级AFTER触发器。

 

  after:表示在数据库动作之后出发器执行。如果存在语句级AFTER触发器,则在SQL语句执行完毕后,要最后执行一次语句级AFTER触发器。

 

  触发事件:指明哪些数据库动作会触发此触发器,指INSERT、DELETE或UPDATE事件,事件可以并行出现,中间用OR连接;

 

  insert:数据库插入会触发此触发器;

 

  update:数据库修改会触发此触发器;

 

  delete:数据库删除会触发此触发器。

 

  表 名:数据库触发器所在的表。

 

  for each row:表示触发器为行级触发器,省略则为语句级触发器,对表的每一行触发器执行一次。

 

  触发器的创建者或具有DROP ANY TIRGGER系统权限的人才能删除触发器。删除触发器的语法如下:

 

  DROP TIRGGER 触发器名

 

  可以通过命令设置触发器的可用状态,使其暂时关闭或重新打开,即当触发器暂时不用时,可以将其置成无效状态,在使用时重新打开。该命令语法如下:

 

  ALTER TRIGGER 触发器名 {DISABLE|ENABLE}

 

  其中,DISABLE表示使触发器失效,ENABLE表示使触发器生效。

 

  同存储过程类似,触发器可以用SHOW ERRORS 检查编译错误。

 

  如果有多个触发器被定义成为相同时间、相同事件触发,且最后定义的触发器是有效的,则最后定义的触发器被触发,其他触发器不执行。触发器体内禁止使用COMMIT、ROLLBACK、SAVEPOINT语句,也禁止直接或间接地调用含有上述语句的存储过程。定义一个触发器时要考虑上述多种情况,并根据具体的需要来决定触发器的种类。

 

  触发器的作用

 

  触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂的参照完整性和数据的一致性。除此之外,触发器还有其它许多不同的功能:

 

  (1) 强化约束(Enforce restriction)

 

  触发器能够实现比CHECK 语句更为复杂的约束。

 

  (2) 跟踪变化Auditing changes

 

  触发器可以侦测数据库内的操作,从而不允许数据库中未经许可的指定更新和变化。

 

  (3) 级联运行(Cascaded operation)。

 

  触发器可以侦测数据库内的操作,并自动地级联影响整个数据库的各项内容。例如,某个表上的触发器中包含有对另外一个表的数据操作(如删除,更新,插入)而该操作又导致该表上触发器被触发。

 

  (4) 存储过程的调用(Stored procedure invocation)。

 

  为了响应数据库更新触,发器可以调用一个或多个存储过程,甚至可以通过外部过程的调用而在DBMS( 数据库管理系统)本身之外进行操作。

 

  由此可见,触发器可以解决高级形式的业务规则或复杂行为限制以及实现定制记录等一些方面的问题。例如,触发器能够找出某一表在数据修改前后状态发生的差异,并根据这种差异执行一定的处理。此外一个表的同一类型(INSERT、 UPDATE、 DELETE)的多个触发器能够对同一种数据操作采取多种不同的处理。

 

  总体而言,触发器性能通常比较低。

 

      当运行触发器时,系统处理的大部分时间花费在参照其它表的这一处理上,因为这些表既不在内存中也不在数据库设备上,而删除表和插入表总是位于内存中。可见触发器所参照的其它表的位置决定了操作要花费的时间长短。

 

 

---------------------------------------------示例说明-----------------------------------------------------------------

 

开始
create trigger biufer_employees_department_id
 before insert or update
  of department_id
  on employees
 referencing old as old_value
     new as new_value
 for each row
 when (new_value.department_id<>80 )
begin
 :new_value.commission_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 update
  of department_id
  on employees
 referencing old as old_value
     new as new_value
 for 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_value.commission_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@hotmail.com’,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_foo
 Before insert or update or delete
  On foo
Begin
 If user not in (‘DONNY’) then
  Raise_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 *from hr.employees

2、 建立日志表
create table employees_log(
  who varchar2(30),
  when date);

3、 在employees_copy表上建立语句触发器,在触发器中填充employees_log 表。
Create or replace trigger biud_employee_copy
  Before insert or update or delete
   On employees_copy
 Begin
  Insert 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 条件谓词,作判断:
begin
  if inserting then
   -----
  elsif updating then
   -----
  elsif deleting then
   ------
  end if;
end;

if updating(‘COL1’) or updating(‘COL2’) then
  ------
end if;

[试验]
1、 修改日志表
alter table employees_log
  add (action varchar2(20));

2、 修改触发器,以便记录语句类型。
Create or replace trigger biud_employee_copy
  Before insert or update or delete
   On employees_copy
 Declare
  L_action employees_log.action%type;
 Begin
  if inserting then
   l_action:=’Insert’;
  elsif updating then
   l_action:=’Update’;
  elsif deleting then
   l_action:=’Delete’;
  else
   raise_application_error(-20001,’You 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’,sysdate,12);

select *from employees_log

update employees_copy set salary=50000 where employee_id = 12345;

2、 行触发器
是指为受到影响的各个行激活的触发器,定义与语句触发器类似,有以下两个例外:
1、 定义语句中包含FOR EACH ROW子句
2、 在BEFORE……FOR EACH ROW触发器中,用户可以引用受到影响的行值。
比如:

定义:
create trigger biufer_employees_department_id
 before insert or update
  of department_id
  on employees_copy
 referencing old as old_value
     new as new_value
 for each row
 when (new_value.department_id<>80 )
begin
 :new_value.commission_pct :=0;
end;
/

Referencing 子句:
执行DML语句之前的值的默认名称是 :old ,之后的值是 :new
insert 操作只有:new
delete 操作只有 :old
update 操作两者都有

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_pk
 before insert on foo
 for each row
begin
 select 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_id
From hr.employees;

尝试更新email和name
update hr.company_phone_book
 set name=’Chen1, Donny1’
where emp_id=100

create or replace trigger update_name_company_phone_book
INSTEAD OF
Update on hr.company_phone_book
Begin
 Update hr.employees
  Set employee_id=:new.emp_id,
   First_name=substr(:new.name, instr(:new.name,’,’)+2),
   last_name= substr(:new.name,1,instr(:new.name,’,’)-1),
   phone_number=:new.phone_number,
   email=:new.email
 where employee_id=:old.emp_id;
end;

 

4、 系统事件触发器
系统事件:数据库启动、关闭,服务器错误

create trigger ad_startup
 after startup
  on database
begin
 -- do some stuff
end;
/


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_trigger
 before drop on donny.schema
begin
 insert 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 系统触发器防止误删除表操作

    在企业级应用中,数据库的安全性和稳定性至关重要。Oracle作为一款广泛使用的数据库管理系统,提供了丰富的功能来保障数据安全。其中,系统触发器是Oracle提供的一种强大工具,能够帮助管理员监控并干预特定的数据库...

    oracle_触发器的种类和触发事件

    Oracle触发器是一种特殊的存储过程,它可以在数据库中自动执行一些操作,主要用于实现数据的完整性、数据的安全性和业务逻辑的实现。触发器可以分为四种类型:DML触发器、DDL触发器、替代触发器和数据库事件触发器。...

    调试oracle触发器方法

    调试Oracle触发器是开发和维护数据库应用程序时的重要步骤,可以帮助我们找出潜在的错误和逻辑问题。下面我们将详细探讨如何调试Oracle触发器。 1. **PL/SQL Developer工具调试**: - PL/SQL Developer是一款强大...

    oracle触发器的创建与使用

    【Oracle触发器的创建与使用】是数据库管理中不可或缺的一部分,尤其在Oracle数据库系统中,触发器扮演着关键角色。触发器是一种存储过程,当特定的数据库事件发生时(如INSERT、UPDATE或DELETE操作),它会被自动...

    oracle 触发器实时调用java 中http接口

    因此,在实际应用中,应谨慎评估是否真的需要在数据库层进行这种集成,或者是否可以考虑消息队列、事件驱动架构等替代方案。 总之,"Oracle触发器实时调用Java中HTTP接口"是一个数据库与应用程序实时通信的示例,...

    关于oracle触发器before和after的应用问题

    本文旨在深入解析Oracle触发器中的Before和After两种触发时机,以及它们在数据库管理和维护中的具体应用。 #### 触发器概述 触发器类似于过程和函数,具有声明、执行和异常处理的部分,但其独特之处在于由特定事件...

    Oracle DML触发器在数据库编程中的应用.pdf

    在实际应用中,DML 触发器可以发挥非常重要的作用。例如,在一个物流系统中,可以使用 DML 触发器来自动更新货物状态、计算运输费用、发送通知邮件等。在一个银行系统中,可以使用 DML 触发器来自动更新账户余额、...

    Oracle中通过触发器来追踪用户的活动

    在实际应用中,为了确保触发器的正确运行,需要注意以下几点: 1. 对于分布式系统(如Oracle并行服务器或RAC集群),记录主机名至关重要,因为可能存在多个远程主机的连接。 2. 为了防止同一时间同一用户名的多次...

    Oracle Form 触发器的执行顺序

    Oracle Form 是 Oracle E-Business Suite R12 中的一个功能强大且灵活的开发工具,用于创建复杂的商业应用程序。其中,触发器(Trigger)是一种非常重要的组件,它可以根据不同的事件来触发相应的操作。 Oracle ...

    oracle数据库触发器实例

    ### Oracle数据库触发器实例解析 #### 一、触发器简介 在Oracle数据库中,触发器是一种存储过程,它被设计为当特定事件(如数据插入、更新...通过这些示例,我们可以看到触发器的强大功能及其在实际应用中的灵活性。

    ORACLE触发器在软件开发中的应用11

    【Oracle触发器在软件开发中的应用】 Oracle触发器在软件开发中扮演着重要的角色,特别是在数据分析和报表制作的场景下。当系统设计中存在冗余数据以满足特定需求时,触发器可以确保这些数据的完整性,防止因更新主...

    oracle函数触发器游标等几个小例子

    在`oracle触发器语法.txt`中,你应该能找到关于触发器的创建、删除以及不同类型的触发器(如行级和语句级)的详细语法。 通过学习这些例子,你将能够更好地理解和应用Oracle中的函数、游标和触发器。实践是掌握这些...

    oracle 数据库 触发器

    Oracle 9i版本引入了多种类型的触发器,这些触发器允许开发者实现复杂的业务逻辑和数据完整性约束,而无需在应用程序中显式调用。 1. **触发器的种类和触发事件**: - **DML触发器**(Data Manipulation Language...

    oracle中记录用户登录信息的触发器的例子

    ### Oracle中记录用户登录信息的触发器实例解析 ...在实际应用中,还可以根据需要对`logon_table`表进行扩展,添加更多字段以记录更详细的信息,如登录方式(如SSH、GUI等)、客户端操作系统版本等。

    oracle 触发器方式实现行ID自增加

    本文将深入探讨如何使用Oracle触发器来实现行ID的自增加。 首先,我们得了解什么是触发器。在Oracle中,触发器是一种数据库对象,它可以在特定的数据库操作(如INSERT、UPDATE或DELETE)发生时自动执行预先定义的...

    Oracle触发器实验报告

    在实际应用中,应避免通过触发器来解决参照完整性问题,而应该依赖于数据库级别的约束来保证数据的完整性和一致性。如果需要在插入新记录前检查是否存在关联记录,可以使用BEFORE INSERT触发器,并在触发器代码中...

    Oracle触发器与存储过程高级编程-第3版itpub.rar

    下面将详细阐述这两个概念以及它们在实际应用中的高级编程技巧。 首先,触发器(Triggers)是Oracle数据库中的一种特殊类型的数据库对象,它能够在特定的数据库事件发生时自动执行。这些事件包括INSERT、UPDATE、...

    数据库oracle触发器课件

    在本课程中,重点讲解的是Oracle中的触发器和包的使用,这两者是数据库开发中的重要工具。 触发器(Trigger)是Oracle数据库中一种预定义的PL/SQL程序,它会在特定的数据库事件(如INSERT、UPDATE、DELETE)发生时...

    oracle通过触发器,实现序列自增

    - 如果应用中存在大量的并发写入操作,可以考虑使用其他机制来减少序列访问的频率,比如预生成一批ID存储在内存中供后续使用。 #### 四、总结 通过上述介绍可以看出,在Oracle数据库中使用触发器结合序列的方式...

    Oracle8触发器系统事件的应用.pdf

    在铁路计算机应用中,Oracle8触发器系统事件的利用可以有效监控和管理调度系统的数据库操作,确保数据的一致性、完整性和安全性。通过合理设置触发器,可以及时发现和处理异常情况,减少因人为错误或系统故障导致的...

Global site tag (gtag.js) - Google Analytics