Oracle中触发器(2)
admin
2023-05-08 15:22:03
0次

   上一篇对触发器的一些基本知识有了了解,在这一篇操作进行验证

before触发器

[oracle@test ~]$ sqlplus / as sysdba

SQL> create user trigger_test identified by 123456 ;
SQL> grant create session to trigger_test ;
SQL> grant create table to trigger_test ;
SQL> grant dba to trigger_test ;
SQL> grant resource to trigger_test ;
SQL> grant create sequence to trigger_test ;

[oracle@test ~]$ sqlplus trigger_test/123456

创建测试表student

SQL> create table student(STUDENT_ID NUMBER(8),name varchar2(15),CREATED_BY VARCHAR2(30) not null,CREATED_DATE DATE not null,MODIFIED_BY VARCHAR2(30) not null,MODIFIED_DATE DATE not null)

创建序列student_id_seq

create sequence student_id_seq
minvalue 1
maxvalue 9999999999999999999999999999
start with 100
increment by 1;
SQL> select * from student ;

no rows selected


SQL> select * from cat ;

TABLE_NAME		       TABLE_TYPE
------------------------------ -----------
STUDENT 		       TABLE
STUDENT_ID_SEQ		       SEQUENCE
create or replace trigger student_before_insert
before insert on student
for each row 
declare
  v_student_id student.student_id%type ;
begin
  select student_id_seq.nextval
  into v_student_id
  from dual ;
  
  :new.student_id := v_student_id ;
  :new.created_by := user ;
  :new.created_date := sysdate ;
  :new.modified_by := user ;
  :new.modified_date := sysdate ;
  
end;
SQL> insert into student (name) values ('mjt');

SQL> commit ;

SQL> select * from student ;

STUDENT_ID NAME 	   CREATED_BY			  CREATED_DATE
---------- --------------- ------------------------------ -------------------
MODIFIED_BY		       MODIFIED_DATE
------------------------------ -------------------
       100 mjt		   TRIGGER_TEST 		  2015-07-29 20:51:19
TRIGGER_TEST		       2015-07-29 20:51:19

SQL> insert into student (name) values ('cxq') ;

1 row created.

SQL> select * from student ;

STUDENT_ID NAME 	   CREATED_BY			  CREATED_DATE
---------- --------------- ------------------------------ -------------------
MODIFIED_BY		       MODIFIED_DATE
------------------------------ -------------------
       100 mjt		   TRIGGER_TEST 		  2015-07-29 20:51:19
TRIGGER_TEST		       2015-07-29 20:51:19

       101 cxq		   TRIGGER_TEST 		  2015-07-29 21:00:54
TRIGGER_TEST		       2015-07-29 21:00:54

after触发器

SQL> create table record(table_name varchar2(30),transaction_name varchar2(10),transaction_user varchar2(30),transaction_date date);

这个表被用来记录数据库中不同表的信息,如,可以记录谁从student表中删除或者更新数据,以及记录时间。

下面的触发器针对对student表的更新或者删除操作,在此之后进行触发

create or replace trigger student_aud
  after update or delete on student
declare
  v_type varchar2(10);
begin
  if updating then
    v_type := 'UPDATE';
  
  elsif deleting then
    v_type := 'DELETE';
  end if;

  update trigger_test.record
     set transaction_user = user, 
     transaction_date = sysdate
   where table_name = 'student'
     and transaction_name = v_type;

  if sql%notfound then
    insert into trigger_test.record values ('student', v_type, user, sysdate);
  end if;

end;
SQL> select * from record ;

no rows selected

SQL> select * from student ;

STUDENT_ID NAME 	   CREATED_BY			  CREATED_DATE
---------- --------------- ------------------------------ -------------------
MODIFIED_BY		       MODIFIED_DATE
------------------------------ -------------------
       100 mjt		   TRIGGER_TEST 		  2015-07-29 20:51:19
TRIGGER_TEST		       2015-07-29 20:51:19

       101 cxq		   TRIGGER_TEST 		  2015-07-29 21:00:54
TRIGGER_TEST		       2015-07-29 21:00:54


SQL> update student set name = 'somebody' where name = 'mjt' ;

1 row updated.

SQL> commit ;

Commit complete.

SQL> select * from student ;

STUDENT_ID NAME 	   CREATED_BY			  CREATED_DATE
---------- --------------- ------------------------------ -------------------
MODIFIED_BY		       MODIFIED_DATE
------------------------------ -------------------
       100 somebody	   TRIGGER_TEST 		  2015-07-29 20:51:19
TRIGGER_TEST		       2015-07-29 20:51:19

       101 cxq		   TRIGGER_TEST 		  2015-07-29 21:00:54
TRIGGER_TEST		       2015-07-29 21:00:54

SQL> select * from record ;

TABLE_NAME		       TRANSACTIO TRANSACTION_USER
------------------------------ ---------- ------------------------------
TRANSACTION_DATE
-------------------
student 		       UPDATE	  TRIGGER_TEST
2015-07-29 21:50:46


SQL> delete student where name = 'somebody' ;

1 row deleted.

SQL> commit ;

Commit complete.

SQL> select * from student ;

STUDENT_ID NAME 	   CREATED_BY			  CREATED_DATE
---------- --------------- ------------------------------ -------------------
MODIFIED_BY		       MODIFIED_DATE
------------------------------ -------------------
       101 cxq		   TRIGGER_TEST 		  2015-07-29 21:00:54
TRIGGER_TEST		       2015-07-29 21:00:54

SQL> select * from record ;

TABLE_NAME		       TRANSACTIO TRANSACTION_USER
------------------------------ ---------- ------------------------------
TRANSACTION_DATE
-------------------
student 		       UPDATE	  TRIGGER_TEST
2015-07-29 21:50:46

student 		       DELETE	  TRIGGER_TEST
2015-07-29 21:56:08


SQL> alter trigger student_aud disable ;

Trigger altered.

SQL> update student set name = 'mjt' where name = 'cxq';

1 row updated.

SQL> commit ;

Commit complete.

SQL> select * from student ;

STUDENT_ID NAME 	   CREATED_BY			  CREATED_DATE
---------- --------------- ------------------------------ -------------------
MODIFIED_BY		       MODIFIED_DATE
------------------------------ -------------------
       101 mjt		   TRIGGER_TEST 		  2015-07-29 21:00:54
TRIGGER_TEST		       2015-07-29 21:00:54

SQL> select * from record ;

TABLE_NAME		       TRANSACTIO TRANSACTION_USER
------------------------------ ---------- ------------------------------
TRANSACTION_DATE
-------------------
student 		       UPDATE	  TRIGGER_TEST
2015-07-29 21:50:46

student 		       DELETE	  TRIGGER_TEST
2015-07-29 21:56:08

禁用触发器之后,在student表上的update操作不再触发产生记录到record表

对应启用

SQL> alter trigger student_aud enable ;

Trigger altered.

3.自治事务


自治事务是由其他事务(通常被称为主事务)发起的独立事务,自治事务也许会执行多个dml语句,并且提交或者回滚,而不会提交或者回滚主事务执行的dml语句。


假如希望即使主事务失败,仍旧能够记录审计数据,这种情况下,主事务是面向

表的update或者delete,需要定义可以独立于主事务进行提交的自治事务。


定义主事务,需要使用autonomous_transaction编译指令在语句块的声明部分

declare 
pragma autonomous_transaction

commit ;

create or replace trigger student_aud
  after update or delete on student  
declare
  v_type varchar2(10);
  pragma autonomous_transaction ;
begin
  if updating then
    v_type := 'UPDATE';
  
  elsif deleting then
    v_type := 'DELETE';
  end if;

  update trigger_test.record
     set transaction_user = user, 
     transaction_date = sysdate
   where table_name = 'student'
     and transaction_name = v_type;

  if sql%notfound then
    insert into trigger_test.record values ('student', v_type, user, sysdate);
  end if;
  commit ;
end;

如果当前更新或者删除表student中的内容,无论成功或者失败,都会在record表中记录当前的操作。不足的是,record表中最多只能记录两条数据,只是当前最新操作的时间以及操作者。

上一篇:oracle基本操作

下一篇:Rman--备份命令

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...