Oracle中触发器(2)

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

before触发器

[[email protected] ~]$ 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 ;

[[email protected] ~]$ 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表中最多只能记录两条数据,只是当前最新操作的时间以及操作者。

时间: 2024-10-12 22:34:26

Oracle中触发器(2)的相关文章

oracle中触发器的讲解

触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来启动运行.即触发器是当某个事件发生时自动地隐式运行.并且,触发器不能接收参数.所以运行触发器就叫触发或点火(firing).ORACLE事件指的是对数据库的表进行的INSERT.UPDATE及DELETE操作或对视图进行类似的操作.ORACLE将触发器的功能扩展到了触发ORACLE,如数据库的启动与关闭等.所以触发器常用来完成由数据库的完整性约束难以完成的复杂业务规则的约束,

Oracle中触发器(1)

Oracle数据库触发器是存储于数据库的命名PL/SQL语句块,当触发事件发生时他们会隐含的执行,执行触发器的活动被称为触发触发器. 特定用户在特定模式下,或者任何用户执行的ddl语句(如create或者alter),这种触发器经常被用于审计目的,并且专用于oracle DBA.可以记录各种模式修改,何时执行.以及那个用户执行的. 系统事件,如数据库启动或者关闭 用户事件,如登录或者注销.即可以定义一个触发器,在用户登录数据库时记录用户名和登录时间. 触发器相关视图: 创建触发器的通用语法: c

oracle 中触发器增加存储过程commit问题

触发器无需commit也不能写commit触发器和触发它的DML是同一个事务DML提交了,触发器的操作也提交了,要不就一起回滚了 当然,如果你一定要在触发器里写COMMIT那就用自治事务相当于一个事务里的子事务 正常情况下,Oracle规定在触发器中不能运行 ddl语句和commit,rollback语句. 解决办法有两种: 1.在可以在触发器中加入:pragma autonomous_transaction; 表示自由事务处理.如: create or replace trigger UPDA

oracle中触发器调用Java程序

1. 写一个Java程序,Java程序的目录是:E:\APP\test\src\test\Main.java 2. 在环境变量Path中配置,E:\studyInstallPath\oracle\BIN 3. 在E:\APP\test\src\test这个目录下执行 4. 5. 创建存储过程 create or replace procedure testmodify(name varchar2) as language Java name 'Main.modify(java.lang.Stri

oracle中触发器报错:未找到数据

select ts.tbcxsx into param_timeLimit from winf_sv_ex_hybs_tbcxsq ts  where ts.sblsh=:new.sblsh and ts.xh=:new.xh; 如果未找到任何记录,后面加一句 Exception when no_data_found then     param_timeLimit := 0;   即可:

【转】oracle中触发器中:new和:old 的使用方法

create or replace trigger TRI_PrintTest before delete or insert or update on TEST_EXAM --触发事件 for each row -- 每修改一行都需要调用此过程 begin dbms_output.put_line(:new.IDNEW); --IDNEW字段更新后的值 dbms_output.put_line(:old.IDNEW); --IDNEW字段更新前的值 end; --原IDNEW字段是1时, --

Oracle中创建触发器示例及注意事项

Oracle中创建触发器示例及注意事项 1.oracle 中创建触发器示例 CREATE TABLE "CONCEPT"."FREQUENCYMODIFYLOG" ( "FREQUENCYID" NUMBER(10,0), "NAME" NVARCHAR2(30), "CODE" VARCHAR2(10 CHAR), "MNEMONICCODE" VARCHAR2(10 CHAR), &

Oracle中的触发器

Oracle中的触发器,布布扣,bubuko.com

Oracle数据库——触发器的创建与应用

一.涉及内容 1.理解触发器的概念.作用和类型. 2.练习触发器的创建和使用. 二.具体操作 (实验) 1.利用触发器对在scott.emp表上执行的DML操作进行安全性检查,只有scott用户登录数据库后才能向该表中执行DML操作.(第1题中,user是系统函数,返回当前用户.字符串中使用两个单引号表示一个单引号.) 要求:分别以system用户和scott用户对emp 表执行DML操作,试验触发器的运行效果. (1)在scott用户下创建触发器 语句: create or replace t