1、触发器的定义 

数据库触发器是一个与表相关联、存储PL/SQL语句的“东西”。每当一个特定的数据操作语句(insert、update、delete)在指定的表上发出时,Oracle自动执行触发器中定义的语句序列。例如:当员工信息插入后,自动输出“插入成功”的信息。

create or replace trigger empTriggerafter insert on emp for each row
declare-- 这里存放本地变量
begindbms_output.put_line('插入成功!');
end empTrigger;

2、触发器的语法 

上面是一个触发器简单的例子,我们接下来看下触发器的语法:

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;

其中:

(1)BEFORE和AFTER指出触发器的触发时序分别为前触发和后触发方式,前触发是在执行触发事件之前触发当前所创建的触发器,后触发是在执行触发事件之后触发当前所创建的触发器。

(2)FOR EACH ROW选项说明触发器为行触发器。行触发器和语句触发器的区别表现在:行触发器要求当一个DML语句操走影响数据库中的多行数据时,对于其中的每个数据行,只要它们符合触发约束条件,均激活一次触发器;而语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。当省略FOR EACH ROW 选项时,BEFORE和AFTER触发器为语句触发器,而INSTEAD OF触发器则只能为行触发器。

(3)REFERENCING子句说明相关名称,在行触发器的PL/SQL块和WHEN子句中可以使用相关名称参照当前的新、旧列值,默认的相关名称分别为OLD和NEW。触发器的PL/SQL块中应用相关名称时,必须在它们之前加冒号(:),但在WHEN子句中则不能加冒号。

(4)WHEN子句说明触发约束条件。Condition为一个逻辑表达时,其中必须包含相关名称,而不能包含查询语句,也不能调用PL/SQL函数。WHEN 子句指定的触发约束条件只能用在BEFORE和AFTER行触发器中,不能用在INSTEAD OF行触发器和其它类型的触发器中。

(5)当一个基表被修改(INSERT、 UPDATE、DELETE)时要执行的存储过程,执行时根据其所依附的基表改动而自动触发,因此与应用程序无关,用数据库触发器可以保证数据的一致性和完整性。

行触发器要求当一个DML语句操作影响数据库中的多行数据时,对于其中的每个数据行,只要它们符合触发约束条件,均激活一次触发器;在行级触发器中,使用:old和:new伪记录变量,识别值的状态。语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。

3、触发器的其他注意事项

触发器名与过程名和包的名字不一样,它是单独的名字空间,因而触发器名可以和表或过程有相同的名字,但在一个模式中触发器名不能相同。

DML触发器的限制:(1)CREATE TRIGGER语句文本的字符长度不能超过32KB。(2)触发器体内的SELECT语句只能为SELECT … INTO结构,或者为定义游标所使用的SELECT语句。(3)触发器中不能使用数据库事务控制语句COMMIT、ROLLBACK语句。(4)由触发器所调用的过程或函数也不能使用数据库事务控制语句。(5)触发器中不能使用LONG、LONG RAW类型。(6)触发器内可以参照LOB类型列的列值,但不能通过 :NEW 修改LOB列中的数据。

4、DML触发器基本要点

(1)触发时机:指定触发器的触发时间。如果指定为BEFORE,则表示在执行DML操作之前触发,以便防止某些错误操作发生或实现某些业务规则;如果指定为AFTER,则表示在执行DML操作之后触发,以便记录该操作或做某些事后处理。

(2)触发事件:引起触发器被触发的事件,即DML操作(INSERT、UPDATE、DELETE)。既可以是单个触发事件,也可以是多个触发事件的组合(只能使用OR逻辑组合,不能使用AND逻辑组合)。

(3)条件谓词:当在触发器中包含多个触发事件(INSERT、UPDATE、DELETE)的组合时,为了分别针对不同的事件进行不同的处理,需要使用ORACLE提供的如下条件谓词。
       1)INSERTING:当触发事件是INSERT时,取值为TRUE,否则为FALSE。
       2)UPDATING [(column_1,column_2,…,column_x)]:当触发事件是UPDATE时,如果修改了column_x列,则取值为TRUE,否则为FALSE。其中column_x是可选的。
       3)DELETING:当触发事件是DELETE时,则取值为TRUE,否则为FALSE。
       (4)解发对象:指定触发器是创建在哪个表、视图上。
       (5)触发类型:是语句级还是行级触发器。
       (6)触发条件:由WHEN子句指定一个逻辑表达式,只允许在行级触发器上指定触发条件,指定UPDATING后面的列的列表。

5、示例

(1)禁止在非工作时间插入数据。

create or replace trigger addEmpInfoCheckbefore insert on emp_info
declare
beginif to_char(sysdate, 'day') in ('星期六', '星期日') orto_number(to_char(sysdate, 'hh24')) not between 9 and 18 then--禁止insert raise_application_error(-20001,'非工作时间禁止插入数据!');end if;
end addEmpInfoCheck;

raise_application_error用于在plsql使用程序中自定义不正确消息。该异常只在数据库端的子程序(流程、函数、包、触发器)中运用,而无法在匿名块和客户端的子程序中运用。语法为raise_application_error(error_number,message[,[truefalse]])。其中error_number用于定义不正确号,该不正确号必须在-20000到-20999之间的负整数;message用于指定不正确消息,并且该消息的长度无法超过2048字节。

(2)涨薪后的工资应该大于涨薪前的工资。

create or replace trigger checkSalarybefore update on salary_info for each row
declare--没有变量声明的话,declare可以省略
beginif :new.sal < :old.sal thenraise_application_error(-20002,'涨后的薪水:'|| :new.sal ||'小于涨前的薪水:'||:old.sal);end if;
end checkSalary;

(3)创建基于值的触发器

create table xzw_test(info varchar2(256));create or replace trigger addDataafter updateon xzw_test for each row
declare
beginif :new.sal > 6000 then insert into xzw_test values(:new.sal ||'-'|| :new.username ||'-'|| :new.job);end if;end addData;

Oracle中的触发器(trigger)相关推荐

  1. oracle中创建触发器

    从csdn上面看到一个如何创建触发器的问题,感觉自己很有必要保存学习,特写下来: 条件: 现有A.B两张表 A: 工号 姓名 密码 性别 年龄 ... B: 工号 姓名 密码 当对A表中的" ...

  2. Oracle中的触发器

    Oracle中的触发器 触发器 触发器(tigger)是在事件发生时隐式地自动运行的 PL/SQL 程序块,不能接收参数,不能被调用,就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行. ...

  3. Oracle一张表写多个触发器,详解oracle中通过触发器记录每个语句影响总行数

    详解oracle中通过触发器记录每个语句影响总行数 需求产生: 业务系统中,有一步"抽数"流程,就是把一些数据从其它服务器同步到本库的目标表.这个过程有可能 多人同时抽数,互相影响 ...

  4. WPF中的触发器(Trigger)

    这节来讲一下WPF中的触发器--Trigger.触发器,是指在既定条件或者特殊场景下被触发,从而去执行一个操作.在WPF中,触发器可以分为以下几类:基本触发器(Trigger):事件触发器(Event ...

  5. mysql添加序列触发器_Oracle中使用触发器(trigger)和序列(sequence)模拟实现自增列实例...

    问题:在SQL Server数据库中,有自增列这个字段属性,使用起来也是很方便的.而在Oracle中却没有这个功能,该如何实现呢? 答:在Oracle中虽然没有自增列的说法,但却可以通过触发器(tri ...

  6. MySQL中的触发器(trigger)

    触发器(trigger)是个特殊的存储过程,不同的是,执行存储过程要使用CALL语句来调用,而触发器的执行不需要使用CALL,也不需要手动启动,当一个预定义的事件发生的时候,就会被MySQL自动调用. ...

  7. oracle中 关于触发器,oracle 闪回关于触发器的bug

    SQL> create table test1 (cola varchar2(10) ); 表已创建. SQL> create table test2 (colb varchar2(10) ...

  8. Oracle中查看触发器使用到的SQL

    一.ORACLE 查出表所有的触发器及触发器详细信息 1.1.查all_triggers表得到trigger_name select trigger_name from all_triggers wh ...

  9. oracle 中触发器的作用是什么,oracle创建触发器及作用举例

    --创建触发器及作用举例 create or replace trigger tri before delete on emp --在删除emp表数据之前需要做的事根据自己的业务去写,before是在 ...

最新文章

  1. ​使用端到端立体匹配网络进行单次 3D 形状测量,用于散斑投影轮廓测量
  2. R语言ggplot2可视化:ggplot2可视化直方图(histogram)并在直方图的顶部外侧(top upper)或者直方图内部添加数值标签
  3. 视觉直观感受7种常用排序算法
  4. 网传B站数据中心起火?所谓“现场图片”却是盗来的
  5. POI实现Excel导出时常用方法说明
  6. 遍历文件夹下所有文件和文件夹
  7. 一起来玩树莓派--解决树莓派启动时屏幕不亮的问题
  8. MySQL安装配置(可视化安装界面),可视化工具安装,连接IDEA,JDBC安装配置,在IDEA中书写第一个MySQL程序,超简单教程(超详细)。
  9. C语言函数库之字符串拷贝函数(string.h)
  10. ngod规范_[转载]NGOD一些感悟
  11. UA用Mode-Driven的使用笔记
  12. r软件读取oracle数据文件,科学网—R软件之读写数据文件 - 刘永辉的博文
  13. MATLAB知识小结
  14. 求助计算机程序员,程序员用代码求救:几近绝望时竟是老本行救了他
  15. 高德地图 定位失败,10: 定位服务启动失败 解决办法
  16. svn 合并分支 idea
  17. modprobe 及 配置文件 /etc/modprobe.conf
  18. wireshark抓图
  19. 数据仓库分层DWD、DWB、DWS
  20. 展讯/北京移动--笔试题

热门文章

  1. DevOps生命周期,你想知道的全都在这里了!
  2. 财报识别OCR披露虚假财务报表
  3. MySql的exists
  4. 碰撞检测 碰撞检测,,碰撞检测是很多动画中必不可少的
  5. Python or html爱心代码(听说最近很火)
  6. 27岁技术总监,收入太高,心头慌得一比。。。
  7. 小游戏:俄罗斯方块(Qt 5.9.8)
  8. 安卓中两种压缩图片详解(比例压缩与质量压缩)
  9. 华师计算机学院2014级,华师,新生早知道
  10. Android GMS Checklist【Android gms认证自检表】