`

Oracle_学习开发子程序_触发器

阅读更多
  触发器是指存放在数据库中,并被隐藏执行的存储过程。在Oracle8i之前,只允许基于表或视图的DML操作(insert,update,delete)建立触发器,在oracle8i之后,不仅支持DML操作,也允许基于系统事件(启动数据库,关闭数据库,登录)和DDL操作建立触发器。
一、触发器简介
   触发器是指隐含执行的存储过程,它可以使用PL/SQL,java和C进行开发,当发生特定事件(例如:修改表、建立对象、登录数据库)时,Oracle会自动执行触发器的相应代码。
触发器由触发事件、触发条件和触发操作三部分组成。
1、触发事件
触发事件是指触发器被触发的SQL、数据库事件和用户事件,在oracle8i之前,触发事件只能是DML操作,在oracle8i之后,不仅支持DML事件,而且还增加了其他事件,具体事件如下:
  • 启动和关闭例程
  • Oracle错误信息
  • 用户登陆和关闭会话
  • 特定表和视图的DML操作
  • DDL语句

2、触发条件(可选)
触发条件是指使用when子句指定一个boolean表达式,当表达式返回true时,则执行触发器相应代码,如果表达式返回false或unknown,则不会执行触发器相应代码。
3、触发操作
触发操作是指包含SQL语句和其他执行代码的PL/SQL块,不仅可以使用PL/SQL开发,也可以使用java或c语言开发,当触发条件为true时,会自动执行触发操作的相应代码。但是在编写触发器执行代码时,需要注意一下限制:
  • 触发代码大小不能超过32k,如果确实需要使用大量代码建立触发器,应该首先建立存储过程,然后在触发器中使用call语句调用存储过程。
  • 触发器代码只能包括insert、update和delete语句,而不能包括DDL语句(create、drop、alert)和事务控制语句(commit,rollback和savepoint)。

二、建立DML触发器
    当建立DML触发器时,需要指定触发时机(before和after)、触发事件(insert、select、update、delete)、表名、触发类型、触发条件以及触发操作。
1、触发时机
  触发时机是指触发器的触发时间,当指定before关键字时,表示在执行DML操作之前触发触发器;当指定after关键字时,表示在执行DML操作之后触发触发器。
2、触发事件
触发条件是指被引起触发器执行的DML语句,即insert、update、delete操作。即可以使用单个触发事件,也可以组合多个触发事件。
3、表名
因为DML触发器是针对特定表执行的,所以必须指定DML操作所对应的表名。
4、触发类型
触发类型用于指定当触发事件发生后,需要执行几次触发操作,如果指定语句触发类型(默认),则只会执行一次触发器代码,如果指定行触发器,则会在每个被作用行上执行一次触发器。
5、触发条件
触发条件用于指定执行触发器代码的条件,只有当条件为true时,才会执行触发器代码,当编写DML触发器时,只能在行触发器上执行触发条件。
6、触发操作
触发操作用于指定触发器执行的代码,如果使用PL/SQL存储过程、java存储过程或外部存储过程,则在触发操作中使用call语句调用相应过程。如果使用PL/SQL匿名块编写触发操作,则按照以下格式编写。
[declare]
  定义变量、常量等。
begin
  编写SQL语句或PL/SQL块。
exception
  编写例外处理语句。
end;

7、DML触发器触发顺序
(1)、DML触发器在单行数据上执行顺序
    对于单行数据而言,无论是语句触发器、还是行触发器,都执行一次,并且执行顺序是
    before语句触发器、before行触发器、DML操作,after行触发器、after语句触发器。
(2)、DML触发器在多行数据上执行顺序
   对于多行数据而言,语句触发器只执行一次,而行触发器则在每个作用行上都执行一次。
三、语句触发器
语句触发器是当执行DML语句时被隐含执行的触发器。注意语句触发器时,不能记录列数据的变化。建立语句触发器的语法如下:
create or replace trigger trigger_name 
   timing event1[or event2 or event3]
 on table_name
pl/sql block;

如上所示:trigger_name用于指定触发器名称,timing用于指定触发时机(before和after),event1用于指定指定触发事件(insert、update、delete),table_name用于指定DML操作对应的表名。
1、建立before语句触发器
   为了禁止工作人员在休息日改变雇员信息,可以建立before语句触发器,以实现数据的安全保护,示例如下:
create or replace trigger trigger_before
before insert or update or delete on cip_tmps
begin
	 if to_char(sysdate,'DY','nls_date_language=AMERICAN')
	  IN ('STA','SUN','THU','WED') then
	  raise_application_error(-20001,'不能在周末修改数据');
	  end if;
end;

  2、使用条件谓词
当在触发器中同时包含多个触发时间(insert、update、delete),为了在触发器代码中区分具体的触发事件、可以使用以下三个条件谓词:
  • INSERTING:当触发条件是insert操作时,该条件谓词返回值为true,否则返回值为false。
  • UPDATING:当触发条件是update操作时,该条件谓词返回值为true,否则返回值为false。
  • DELETING:当触发条件是delete操作时,该条件谓词返回值为true,否则返回值为false。

下面示例说明在触发器中使用这三个条件谓词的方法,示例如下:
create or replace trigger trigger_before
before insert or update or delete on cip_tmps
begin
	 if to_char(sysdate,'DY','nls_date_language=AMERICAN')
	  IN ('STA','SUN','THU','WED') then
	  case 
	  when inserting then
	    raise_application_error(-20001,'不能在周末添加数据');
	  when updating then
	    raise_application_error(-20002,'不能在周末修改数据');
	  when deleting then
	    raise_application_error(-20003,'不能在周末删除数据');
		end case;
	  end if;
end;

3、建立after语句触发器
在往cip_temp表中插入数据时,同时往cip_temps表中插入数据,必备条件是,cip_temp表中必须有一个字段标示是最后插入的那条记录。
create or replace trigger trigger_after
after insert on cip_temp
begin
insert into cip_temps (select * from(select * from cip_temp order by id) where rownum=1);
end;

四、建立行触发器
行触发器是指执行DML操作时,每作用一行就触发一次触发器。建立行触发器语法如下:
create or replace trigger trigger_name 
   timing event1[or event2 or event3]
 on table_name
[REFERENCING NEW AS NEW | OLD AS OLD]
for each row
pl/sql block;

如上所示:trigger_name用于指定触发器名称,timing用于指定触发时机(before和after),event1用于指定指定触发事件(insert、update、delete),table_name用于指定DML操作对应的表名。REFERENCING 子句用于指定引用新、旧、数据方式,默认情况下使用old修饰符引用旧数据,使用new修饰符是引用新数据。for each row表示建立行触发器。
1、建立before行触发器
确保员工工资不能涨价,示例如下:
create or replace trigger trigger_before_row
before update on cip_tmp
for each row
begin
  if(:new.id <>:old.id) then
  raise_application_error(-20001,'员工工资不能调整');
  end if;
end;

2、建立after行触发器
做到更新、删除、添加一个表中的数据,则另一个表也相应的更新、删除、添加。
create or replace trigger trigger_after_row
after insert or update or delete on cip_test
for each row
declare
v_update int;
v_delete int;
begin
case 
  when inserting then
    insert into cip_temps values(:new.name,:new.age,:new.address,:new.id);
  when updating then
	  select count(*) into v_update from cip_temps where id=:old.id;
	  if(v_update=0) then
	  insert into cip_temps values(:new.name,:new.age,:new.address,:new.id);
	  else
            update cip_temps set name=:new.name,age=:new.age,address=:new.address 
            where id=:old.id;
	  end if;
  when deleting then
    select count(*) into v_delete from cip_temps where id=:old.id;
    if(v_delete<>0)then
     delete from cip_temps where id=:old.id;
    end if;
   end case;   
end;

3、限制行触发器
当使用行触发器时,默认情况下会作用在每行执行一次触发器,为了在特定条件下执行行触发器代码,就需要使用when子句对触发条件加以限制。
示例如下:
create or replace trigger trigger_after_row_when
after  update or delete on cip_test
for each row
when (old.name='aa8')
declare
v_update int;
begin
case 
  when updating then
	  select count(*) into v_update from cip_temps where id=:old.id;
	if(v_update=0) then
	 insert into cip_temps values(:new.name,:new.age,:new.address,:new.id);
	else
update cip_temps set name=:new.name,age=:new.age,address=:new.address where id=:old.id;
	end if;
   end case;   
end;

4、DML触发器使用注意事项
当编写DML触发器时,触发器代码不能从触发器所对应的表中读取数据。
5、实现参照完整性
参照完整性是指两个表具有主从关系(主外健关系),当删除主表数据时,必须确保相应的从表的数据也被删除,可以在定义外键约束时指定on delete cascade。
五、行触发器和语句触发器区别
1、行触发器有 for each row子句。语句触发器没有for each row 子句。
2、行触发器,可以有 when 作为触发限制,可以使用new/old。语句触发器不能有when 作为触发限制。
3、行触发器:对应DML语句所影响到的表中的每一行,触发器都要执行一遍。
4、语句触发:对应DML语句所影响到的表中的所有行,触发器只执行一遍。
对表进行行级触发的,则该表暂时不能操作(即该表已经成为变异表)表 级触发器与此不同
分享到:
评论

相关推荐

    ORACLE PL/SQL 存储过程 触发器

    ORACLE PL/SQL 存储过程 触发器 ORACLE PL/SQL 存储过程 触发器 子程序 游标

    Oracle_Database_11g完全参考手册.part3/3

    通过学习《Oracle Database 11g完全参考手册》,您可以了解如何实现最新的安全措施,如何调优数据库的性能,如何部署网格计算技术。附录部分内容丰富、便予参照,包括Oracle命令、关键字、功能以及函数等。 目录 ...

    Oracle_Database_11g完全参考手册.part2/3

    通过学习《Oracle Database 11g完全参考手册》,您可以了解如何实现最新的安全措施,如何调优数据库的性能,如何部署网格计算技术。附录部分内容丰富、便予参照,包括Oracle命令、关键字、功能以及函数等。 目录 ...

    Oracle10数据库电子教案

    Oracle10数据库电子教案 第1章 Oracle Database 10g数据库基础 第2章 Oracle Database 10g的安装及运行环境 第3章 数据库和表的基本操作 第4章 数据操作及完整性 第5章 SQL查询技术 ...第12章 数据库应用系统开发

    oracle学习资料

    §7.5 子程序重载 13 §7.6 删除过程、函数和包 13 §7.7 包的管理 13 第八章 触发器 13 §8.1 触发器类型 13 §8.1.1 DML触发器 13 §8.1.2 替代触发器 13 §8.1.3 系统触发器 13 §8.2 创建触发器 13 §8.2.1 ...

    实验六-触发器实验报告.doc

    如果由触发器调用存储子过程,则存储子程序不能包括事务控制语句 。 :old 和 :new 值的类型不能是 LONG 和 LONG RAW。 [实验内容] 1. 给Customer表增加一列Savings,类型为int,来存放每个顾客的存款总额。 ALTER ...

    《Oracle数据库开发实用教程》电子教案

    总 目 录 第1章 数据库引论 ...第5章 PL/SQL程序块 第6章 存储过程与函数 第7章 PL/SQL包与触发器 第8章 数据库对象 第9章 权限、角色与用户 第10章 Oracle数据库的逻辑备份 第11章 数据库设计过程与方法

    Oracle 10g应用指导

    包括加密Oracle子程序,存储应用程序用户名和口令,禁止修改删除数据库对象,Oracle数据加密以及丢失SYSMAN及资料档案库用户口令的解决方法。书中给出了丰富的图表,多数图例是作者根据多年实践总结出来的,图示简练...

    Oracle8i PL/SQL高级程序设计 高清晰版

    共分为7部分(7个pdf文档): 第一部分:PL/SQL介绍及开发环境 1.PL/SQL介绍 2.PL/SQL开发和运行环境 3.跟踪和调试 ...4.创建子程序和包 5.使用子程序和包 6.数据库触发器 7.数据库作业和文件输入输出

    Oracle帮助文档

    Oracle帮助文档 ... 子程序/过程(procedure) 子程序/函数 事务处理 触发器 包 范式 数据备份(exp)与恢复(imp) 归档方式 过程练习题 考试题_查询部分 考试题_查询部分(2) 考试题_pl/sql 习题_触发器

    oracle实验报告

    2、 定义一个为修改职工表(emp)中某职工工资的存储过程子程序,职工名作为形参,若该职工名在职工表中查找不到,就在屏幕上提示“查无此人”然后结束子程序的执行;否则若工种为MANAGER的,则工资加$1000;工种为...

    Oracle+10g应用指导与案例精讲

    包括加密Oracle子程序,存储应用程序用户名和口令,禁止修改删除数据库对象,Oracle数据加密以及丢失SYSMAN及资料档案库用户口令的解决方法。书中给出了丰富的图表,多数图例是作者根据多年实践总结出来的,图示简练...

    plsql_oracle 编程

    §7.5 子程序重载 13 §7.6 删除过程、函数和包 13 §7.7 包的管理 13 第八章 触发器 13 §8.1 触发器类型 13 §8.1.1 DML触发器 13 §8.1.2 替代触发器 13 §8.1.3 系统触发器 13 §8.2 创建触发器 13 §8.2.1 ...

    Oracle基础学习

    Oracle的学习 1.Oracle 入门 2.SQL 查询和 SQL 函数 3.锁和表分区 4.数据库对象 5.使用 PL/SQL 6.游标管理 7.子程序和程序包 8.触发器和内置程序包 9.备份与恢复简介

    Oracle 10g 开发与管理

    本文是由笔者2012年学习oracle数据库时编写的学习札记,其中的题目 多数为老师留下的思考题目。 我相信本文会对初学者使用oracle有一个初步的使用印象。右图为我所参 考的书籍。 目录 第一讲 Oacle关系数据库 ...

    Oracle8i_9i数据库基础

    第一部分 Oracle SQL*PLUS基础 23 第一章 Oracle数据库基础 23 §1.1 理解关系数据库系统(RDBMS) 23 §1.1.1 关系模型 23 §1.1.2 Codd十二法则 24 §1.2 关系数据库系统(RDBMS)的组成 24 §1.2.1 RDBMS 内核 24...

    Oracle Database 11g完全参考手册中文版.part1

    全部分两部分打包上传,此为第一部分。 简介:初学oracle必须的学习手册,初学...构建和调整PL/SQL触发器、函数和程序包 使用Java、JDBC和XMIL开发数据库应用程序 使用Oracle实时应用群集(RAC)优化可用性和可扩展性

    Oracle11g从入门到精通2

    对于初学者,《Oracle11g从入门到精通》是一本很好的入门教程,对Oracle管理员和应用程序开发员,也有很好的学习和参考价值。  Oracle数据库系统是数据库领域最优秀的数据库之一,《Oracle11g从入门到精通》以...

Global site tag (gtag.js) - Google Analytics