trigger

trigger

一、类型:

  DML触发器:insert、update、delete

  替代触发器:针对视图

  系统触发器:针对系统事件

二、触发频率:

  语句级(statement):当触发事件发生时,该触发器只执行一次;

  行级(row):当触发事件发生时,针对会受到影响的每一行数据,触发器都会执行一次;

三、注意:

  一个表最多只能有12个触发器,且相互不可矛盾、重复;

  单个触发器最多为32KB;

  触发器中不能包含事物控制语句(commit,rollback,savepoint);且其中调用的过程和函数语句中也不能有事物控制语言;

  当触发器中有 “for each row” 选项时,则表示为语句级触发器;

    缺省 “for each row” 选项时,before 和 after 触发器为语句级触发器,instead of 触发器为行触发器;

  系统事件:

    startup           启动数据库实例之后

    shutdown          关闭数据库实例之前

    servererror       出现错误之后

    logon             连接之后

    logoff            断开连接之前

    create

    drop

    alter

    ddl

    grant

    revoke

    rename

    audit/noaudit

四、语法:

create or replace trigger 触发器名 出发时间 触发事件

  on 表名 [for each row]

  [when condition]

  [pl/sql]

五、实例:

5.1、简单 after update

create table test_dept as select * from test_dept;
create or replace trigger test_trigger01
       after update
       on test_dept for each row
begin
       dbms_output.put_line(:old.deptno||‘=++++++=‘||:new.deptno);
end;

update test_dept set b=‘11111‘ where a=‘a‘;
commit;

drop trigger test_trigger01;
drop table test_dept;

5.2、deleting,updating,inserting应用,将某表中的数据修改记录插入到另一张表中

--deleting   只有:old
 --inserting  只有:new
 --updating   :old和:new都有

create table test_dept as select * from dept;
create table test_dept_log as select a.*,‘删除‘ as flag,sysdate as time_ from dept a where 1=2;

create or replace trigger test_trigger02
       after update or delete or insert
       on test_dept for each row
begin
       case
         when updating then
              insert into test_dept_log values(:old.deptno,:old.dname,:old.loc,‘修改‘,sysdate);
         when inserting then
              insert into test_dept_log values(:new.deptno,:new.dname,:new.loc,‘插入‘,sysdate);
         when deleting then
              insert into test_dept_log values(:old.deptno,:old.dname,:old.loc,‘删除‘,sysdate);
       end case;
       /*--也可以写成:
         if updating then
              insert into test_dept_log values(:old.deptno,:old.dname,:old.loc,‘修改‘,sysdate);
         elsif inserting then   --【注意是elsif,而不是elseif】
              insert into test_dept_log values(:new.deptno,:new.dname,:new.loc,‘插入‘,sysdate);
         elsif deleting then
              insert into test_dept_log values(:old.deptno,:old.dname,:old.loc,‘删除‘,sysdate);
         end if;
       */
end;

update test_dept set loc=‘test‘ where deptno=20;
insert into test_dept values(50,‘wer‘,‘wer‘);
delete from test_dept where deptno=50;
select * from test_dept_log;
select * from test_dept;  

drop table test_dept;
drop table test_dept_log;
drop trigger test_trigger02;

5.3、当前用户不是scott,则不允许修改

create table test_dept as select * from dept;
create or replace trigger test_trigger03
       before update or insert or delete
       on test_dept
       for each row
--when ((select count(*) from dual where user)=‘SCOTT‘>0)
when (upper(user)<>‘SCOTT‘)
declare tt varchar2(20);
begin
  select user into tt from dual;
  raise_application_error(-20001,‘当前用户是‘||tt||‘,没有操作权限!‘);
end;

update test_dept set loc=‘test_‘ where deptno=20;
select * from test_dept;

drop table test_dept;
drop trigger test_trigger03;

5.4、instead of触发器,建立在视图上,且该视图没有指定 with check option 选项;

create table test01(
       a number(10),
       b number(10),
       c number(10));
create table test02 as
       select * from test01 where 1=2;
create view test_view01 as
       select a.a,b.b from test01 a,test02 b where a.a=b.a and a.b=b.b;

create or replace trigger test_trigger04
       instead of insert
       on test_view01
       for each row
begin
       --raise_application_error(-20001,‘视图不可插入数据!‘);
       insert into test01 values (:new.a,null,null);
       insert into test02 values (null,:new.b,null);
end;

insert into test_view01 values(1,1);
insert into test_view01
       select 2,2 from dual
       union all
       select 3,3 from dual;
select * from test01;
select * from test02;

drop view test_view01;
drop trigger test_trigger04;
drop table test02;
drop table test01;

5.5、将用户登陆和登出记录到数据表
--创建系统触发器,用户需要有administer database trigger权限
--以下操作在sys用户下可成功完成

create table test_login(
       event_ varchar2(10),
       user_ varchar2(20),
       address_ varchar2(100),
       date_ date
       );
create or replace trigger test_trigger05
       after logon on database
begin
       insert into test_login values(‘登陆‘,user,ora_client_ip_address,sysdate);
end;        

create or replace trigger test_trigger06
       before logoff on database
begin
       insert into test_login values(‘登出‘,user,ora_client_ip_address,sysdate);
end; 

drop table test_login;
drop trigger test_trigger05;
drop trigger test_trigger06;
时间: 2024-10-19 10:47:02

trigger的相关文章

SQLServer与Oracle的数据同步(触发器trigger)

说到同步,其实是靠"作业"定时调度存储过程来操作数据,增,删,改,全在里面,结合触发器,游标来实现,关于作业调度,使用了5秒运行一次来实行"秒级作业",这样基本就算比较快的"同步" 做的是SQL Server往Oracle端同步,先在sql server上建立往Oracle端的链接服务器,我用一个视图"封装"了一下链接服务器下的一张表. create view v_ora_PUBLISHLASTREC as select *

使用Trigger审计一张表的DML操作

最近ogg的灾备端复制进程中的一张表老是报错ORA-04031,但是又查不到原因,于是想用审计的方法来看到底这张表是被谁做了DML操作,把数据搞没了.本来想用数据库自带的审计功能参考:http://hbxztc.blog.51cto.com/1587495/1870181 但是需要重启数据库,就放弃了,上网查资料看到有人用触发器来实现这个功能,于是自己也做了尝试. 平台11.2.0.4 [email protected]>select * from v$version; BANNER -----

Writing On-Error Trigger In Oracle Forms

Suppose you want to handle an error in oracle forms and want to display custom error message for that error, but also you want to customize more for a particular error. For example there are many fields in form with required property is set to TRUE f

An Example of On-Error Trigger in Oracle Forms

I wrote this trigger around 4 years ago to handle errors in an application based on Oracle Forms 6i. This trigger handles all errors with some custom messages for some specific errors and not only this after giving an appropriate message to the user

Zabbix 3.0 监控交换机(CPU、内存监控及配置Trigger)

一.zabbix监控CPU 1.zabbix监控CPU及配置Triggers (1).要用到的OID        1.3.6.1.4.1.9.2.1.57.0  CPU utilization for one minute        1.3.6.1.4.1.9.2.1.58.0  CPU utilization for five minutes        1.3.6.1.4.1.9.2.1.56.0  CPU utilization for five seconds (1).创建ite

Trigger 触发器

本文非原创 一.触发器: 是一种特殊的存储过程,其特殊性在于它并不需要用户来执行. 调用,在表中数据进行修改时,自动执行,来实现复杂的完整性约束, 防止对数据不正确的修改. 1.定义:它是一段能够自动执行的程序,当对象进行 update,insert, delete 时,自动执行,它没有参数,不允许被调用. 2.触发器的优点: (1)级联修改 (2)实现复杂约束 (3)检查数据 (4)控制修改表时合乎业务规则 二.触发器的激活时机: 1.后触发:当引起触发器执行的修改语句执行完成,并通过约束后才

post-receive in Windows---git hooks trigger Jenkins to build artifcat

如何在Windows上编写post-receive,当git用户push文件到git server时.检查commit message,如果包含RUN_BUILD就调用Jenkins build API编译项目. 环境设置: 1. 安装Jenkins ---流行的代码管理工具 选择Remote trigger scripts 在Jenkins Job build 配置项. 2. 安装scm-manager ---同时支持svn,git... 3. 安装git-client---需要用到git c

jquery中的trigger和triggerHandler区别

我们在jQuery基础教程之如何注册以及触发自定义事件这篇文章中,有用到今天要讲的trigger方法.今天我们来简单看看jquery中的trigger何triggerHandler方法的区别:trigger( event, [data] )在每一个匹配的元素上触发某类事件.这个函数也会导致浏览器同名的默认行为的执行.比如,如果用trigger()触发一个'submit',则同样会导致浏览器提交表单.如果要阻止这种默认行为,应返回false.你也可以触发由bind()注册的自定义事件 $("p&q

关于c#一些关键字和Unity Trigger

1.c#中sealed关键字,可理解为密封,不可被继承 用于方法和属性时 必须跟override一起(对应java中的final 当final修饰变量时 对应c#中的readonly)2.vritual虚 自身可以有实现 子类可以选择重写 abstract 抽象 自身不能有实现 子类一定要实现 3.new覆盖 override重写 都不会改变父类自身的功能 Base b = new Base() 4.用子类创建父类时 重写会调用子类的功能 而覆盖不会 Base b = new Child()4.

jquery的自定义事件通过on绑定trigger触发

jquery绑定自定义事件,可以实现预先绑定好一个处理方法,当需要使用的时候利用jquery trigger来触发自定义事件,以达到方便快捷的目的.我们来假设一个这样的场景,一个textarea中的字数计算,如果是直接键盘输入或者粘贴进来的话,是可以使用input方法检测到,但是如果是通过js插入的文本,这个时候input事件就监测不到了,这个时候如果我们事先给绑定一个myChange事件,它的回调函数就是来处理计算其中的文本字数的,我们在使用js给这个textarea赋值以后,连缀写上.tri