Oracle 触发器语法及实例(二)

2016-02-19 18:31 14 1 收藏

最近很多朋友喜欢上设计,但是大家却不知道如何去做,别担心有图老师给你解答,史上最全最棒的详细解说让你一看就懂。

【 tulaoshi.com - 编程语言 】

  2、触发器的类型有:

  触发器类型:     

  1、 语句触发器

  2、 行触发器

  3、INSTEAD OF触发

  4、 系统条件触发器

  5、 用户事件触发器

  2.1、语句级触发器.(语句级触发器对每个DML语句执行一次)

  是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器。能够与INSERT、UPDATE、DELETE或者组合上进行关联。但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次。比如,无论update多少行,也只会调用一次update语句触发器。

  实例:  

   createorreplacetriggertri_test
  afterinsertorupdateordeleteontest
  begin
  ifupdatingthen
  dbms_output.put_line('修改');
  elsifdeletingthen
  dbms_output.put_line('删除');
  elsifinsertingthen
  dbms_output.put_line('插入');
  endif;
  end;

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  2.2、行级触发器.(行级触发器对DML语句影响的每个行执行一次)

  实例一:

  触发器  

  行级触发器

   createtabletest(sidnumber,snamevarchar2(20));--创建一个表
  createsequenceseq_test;--创建序列
  createorreplacetriggertri_test--创建触发器
  beforeinsertorupdateofsidontest
  foreachrow--触发每一行
  begin
  ifinsertingthen
  selectseq_test.nextvalinto:new.sidfromdual;
  else
  raise_application_error(-20020,'不允许更新ID值!');--中断程序
  endif;
  end;

  测试,插入几条记录  

   insertintotestvalues(0,'ff');
  insertintotestvalues(0,'ff');
  insertintotestvalues(0,'tt');

  实例二:

  创建一个触发器,无论用户插入新记录,还是修改emp表的job列,都将用户指定的job列的值转换成大写.

   createorreplacetriggertrig_job
  beforeinsertorupdateofjob
  onemp
  foreachrow
  begin
  ifinsertingthen
  :new.job:=upper(:new.job);
  else
  :new.job:=upper(:new.job);
  endif;
  end;

  2.3、instead of触发器.

  (此触发器是在视图上而不是在表上定义的触发器,它是用来替换所使用实际语句的触发器.)

  语法如下:

   createorreplacetriggertrig_test
  insteadofinsertorupdateon表名
  referencingnewasn
  foreachrow
  declare
  ..........
  begin
  ........
  end;

  2.4、模式触发器.

  可以在模式级的操作上建立触发器.

  实例如下: 

   createorreplacetriggerlog_drop_obj
  afterdroponschema
  begin
  insertinto.....
  end;

  2.5、数据库级触发器.

  可以创建在数据库事件上的触发器,包括关闭,启动,服务器错误,登录等.这些事件都是实例范围的,不与特定的表或视图关联.

  实例:  

   createorreplacetriggertrig_name
  afterstartupondatabase
  begin
  ...........
  end;

  2.6、例子:

  需要对在表上进行DML操作的用户进行安全检查,看是否具有合适的特权。 

   Createtablefoo(anumber);
  Createtriggerbiud_foo
  Beforeinsertorupdateordelete
  Onfoo
  Begin
  Ifusernotin(‘DONNY’)then
  Raise_application_error(-20001,‘Youdon’thaveaccesstomodifythistable.’);
  Endif;
  End;
  /

  即使SYS,SYSTEM用户也不能修改foo表

  2.7、[试验]

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  对修改表的时间、人物进行日志记录。

  1、 建立试验表 

   createtableemployees_copyasselect*fromhr.employees

  2、 建立日志表

   createtableemployees_log(
  whovarchar2(30),
  whendate);

  3、 在employees_copy表上建立语句触发器,在触发器中填充employees_log表。 

   Createorreplacetriggerbiud_employee_copy
  Beforeinsertorupdateordelete
  Onemployees_copy
  Begin
  Insertintoemployees_log(Who,when)
  Values(user,sysdate);
  End;
  /

  4、 测试

  updateemployees_copysetsalary=salary*1.1;
  select*fromemployess_log;

  5、 确定是哪个语句起作用?

  即是INSERT/UPDATE/DELETE中的哪一个触发了触发器?

  可以在触发器中使用INSERTING / UPDATING / DELETING条件谓词,作判断:  

   begin
  ifinsertingthen
  -----
  elsifupdatingthen
  -----
  elsifdeletingthen
  ------
  endif;
  end;
  ifupdating(‘COL1’)orupdating(‘COL2’)then
  ------
  endif;


  2.8、[试验]

  1、 修改日志表

   altertableemployees_log
  add(actionvarchar2(20));

  2、 修改触发器,以便记录语句类型。  

   then
  l_action:=’Delete’;
  else
  raise_application_error(-20001,’Youshouldneverevergetthiserror.’);
  Insertintoemployees_log(Who,action,when)
  Values(user,l_action,sysdate);
  End;Createorreplacetriggerbiud_employee_copy
  Beforeinsertorupdateordelete
  Onemployees_copy
  Declare
  L_actionemployees_log.action%type;
  Begin
  ifinsertingthen
  l_action:=’Insert’;
  elsifupdatingthen
  l_action:=’Update’;
  elsifdeleting 
  /

  3、测试

   insertintoemployees_copy(employee_id,last_name,email,hire_date,job_id) 
  values(12345,’Chen’,’Donny@hotmail’,sysdate,12); 
  select*fromemployees_log

来源:http://www.tulaoshi.com/n/20160219/1617971.html

延伸阅读
约定和编程风格 每次我想要演示实际代码时,我会对mysql客户端的屏幕就出现的代码进行调整,将字体改成Courier,使他们看起来与普通文本不一样(让大家区别程序代码和正文)。在这里举个例子: mysql DROP FUNCTION f; Query OK, 0 rows affected (0.00 sec) 如果实例比较大,则需要在某些行和段落间加注释,同时我会用将"--"符号放在页面的...
Conventions and Styles约定和编程风格 每次我想要演示实际代码时,我会对mysql客户端的屏幕就出现的代码进行调整,将字体改成Courier,使他们看起来与普通文本不一样(让大家区别程序代码和正文)。在这里举个例子: mysql DROP FUNCTION f; Query OK, 0 rows affected (0.00 sec) 如果实例比较大,则需要在某些行和段落间加注释,...
Conventions and Styles约定和编程风格 每次我想要演示实际代码时,我会对mysql客户端的屏幕就出现的代码进行调整,将字体改成Courier,使他们看起来与普通文本不一样(让大家区别程序代码和正文)。在这里举个例子: mysql DROP FUNCTION f; Query OK, 0 rows affected (0.00 sec) 如果实例比较大,则需要在某些行和段落间加注...
标签: SQLServer
如果一个触发器在执行操作时引发了另一个触发器,而这个触发器又接着引发下一个触发器……这些触发器就是嵌套触发器。触发器可嵌套至 32 层,并且可以控制是否可以通过"嵌套触发器"服务器配置选项进行触发器嵌套。 如果允许使用嵌套触发器,且链中的一个触发器开始一个无限循环,则超出嵌套级,而且触发器将终止。 可使用嵌套触发器...
你可能了解以前的USERENV函数,它返回会话值,如用户会话ID、语言、以及用户是否拥有数据库管理员权限。虽然由于遗留原因,USERENV函数仍在使用,但在Oracle 8i中,它已被一个新的函数所替代——SYS_CONTEXT。 SYS_CONTEXT不仅能够返回USERENV数据——它还能返回应用程序定义的数据值。应用程序上下文包括一组可以被SYS_CONTEXT返回的名称...

经验教程

846

收藏

88
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部