CREATE OR REPLACE TRIGGER bef_ins_ceo_comp AFTER INSERT ON ceo_compensation FOR EACH ROW DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO ceo_comp_history VALUES (:NEW.name, :OLD.compensation, :NEW.compensation, 'AFTER INSERT', SYSDATE); COMMIT; END; 更多请查看帮助。
触发器触发器 是特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。 功能:1、 允许/限制对表的修改2、 自动生成派生列,比如自增字段3、 强制数据一致性4、 提供审计和日志记录5、 防止无效的事务处理6、 启用复杂的业务逻辑 开始create trigger biufer_employees_department_id before insert or update of department_id on employees referencing old as old_value new as new_value for each row when (new_value.department_id<>80 )begin :new_value.commission_pct :=0;end;/ 触发器的组成部分:1、 触发器名称2、 触发语句3、 触发器限制4、 触发操作 1、 触发器名称create trigger biufer_employees_department_id命名习惯:biufer(before insert update for each row)employees 表名department_id 列名 2、 触发语句比如:表或视图上的DML语句DDL语句数据库关闭或启动,startup shutdown 等等before insert or update of department_id on employees referencing old as old_value new as new_value for each row 说明:1、 无论是否规定了department_id ,对employees表进行insert的时候2、 对employees表的department_id列进行update的时候 3、 触发器限制when (new_value.department_id<>80 ) 限制不是必须的。此例表示如果列department_id不等于80的时候,触发器就会执行。其中的new_value是代表更新之后的值。 4、 触发操作是触发器的主体begin :new_value.commission_pct :=0;end; 主体很简单,就是将更新后的commission_pct列置为0 触发:insert into employees(employee_id,last_name,first_name,hire_date,job_id,email,department_id,salary,commission_pct )values( 12345,’Chen’,’Donny’, sysdate, 12, ‘[email protected]’,60,10000,.25); select commission_pct from employees where employee_id=12345; 触发器不会通知用户,便改变了用户的输入值。 触发器类型:1、 语句触发器2、 行触发器3、 INSTEAD OF 触发器4、 系统条件触发器5、 用户事件触发器 1、 语句触发器是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器。能够与INSERT、UPDATE、DELETE或者组合上进行关联。但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次。比如,无论update多少行,也只会调用一次update语句触发器。 例子:需要对在表上进行DML操作的用户进行安全检查,看是否具有合适的特权。Create table foo(a number); Create trigger biud_foo Before insert or update or delete On fooBegin If user not in (‘DONNY’) then Raise_application_error(-20001, ‘You don’t have access to modify this table.’); End if;End;/ 即使SYS,SYSTEM用户也不能修改foo表 [试验]对修改表的时间、人物进行日志记录。 1、 建立试验表create table employees_copy as select *from hr.employees 2、 建立日志表create table employees_log( who varchar2(30), when date); 3、 在employees_copy表上建立语句触发器,在触发器中填充employees_log 表。Create or replace trigger biud_employee_copy Before insert or update or delete On employees_copy Begin Insert into employees_log( Who,when) Values( user, sysdate); End; /4、 测试update employees_copy set salary= salary*1.1; select *from employess_log; 5、 确定是哪个语句起作用?即是INSERT/UPDATE/DELETE中的哪一个触发了触发器?可以在触发器中使用INSERTING / UPDATING / DELETING 条件谓词,作判断:begin if inserting then ----- elsif updating then ----- elsif deleting then ------ end if;end; if updating(‘COL1’) or updating(‘COL2’) then ------end if; [试验]1、 修改日志表alter table employees_log add (action varchar2(20)); 2、 修改触发器,以便记录语句类型。Create or replace trigger biud_employee_copy Before insert or update or delete On employees_copy Declare L_action employees_log.action%type; Begin if inserting then l_action:=’Insert’; elsif updating then l_action:=’Update’; elsif deleting then l_action:=’Delete’; else raise_application_error(-20001,’You should never ever get this error.’); Insert into employees_log( Who,action,when) Values( user, l_action,sysdate); End; / 3、 测试insert into employees_copy( employee_id, last_name, email, hire_date, job_id) values(12345,’Chen’,’Donny@hotmail’,sysdate,12); select *from employees_log
PRAGMA AUTONOMOUS_TRANSACTION; 这是什么意思?能解释下吗?谢谢
理论知识: AUTONOMOUS TRANSACTION(自治事务)的介绍:在基于低版本的ORACLE做一些项目的过程中,有时会遇到一些头疼的问题.,比如想在执行当前一个由多个DML组成的transaction(事务)时,为每一步DML记录一些信息到跟踪表中,由于事务的原子性,这些跟踪信息的提交将决定于主事务的commit或rollback. 这样一来写程序的难度就增大了, 程序员不得不把这些跟踪信息记录到类似数组的结构中,然后在主事务结束后把它们存入跟踪表.哎,真是麻烦!有没有一个简单的方法解决类似问题呢?ORACLE8i的AUTONOMOUS TRANSACTION(自治事务,以下AT)是一个很好的回答。AT 是由主事务(以下MT)调用但是独立于它的事务。在AT被调用执行时,MT被挂起,在AT内部,一系列的DML可以被执行并且commit或rollback.注意由于AT的独立性,它的commit和rollback并不影响MT的执行效果。在AT执行结束后,主事务获得控制权,又可以继续执行了。如何实现AT的定义呢?我们来看一下它的语法。其实非常简单。只需下列PL/SQL的声明部分加上PRAGMA AUTONOMOUS_TRANSACTION 就可以了。1. 顶级的匿名PL/SQL块2. Functions 或 Procedure(独立声明或声明在package中都可)3. SQL Object Type的方法4. 触发器。 比如: 在一个独立的procedure中声明ATCREATE OR REPLACE PROCEDURE Log_error(error_msg IN VARCHAR2(100))IS PRAGMA AUTONOMOUS_TRANSACTION;BEGIN Insert into Error_log values ( sysdate,error_msg); COMMIT;END;下面我们来看一个例子,(win2000 advanced server + oracle8.1.6 , connect as scott)建立一个表:create table msg (msg varchar2(120));首先,用普通的事务写个匿名PL/SQL块: declare cnt number := -1; --} Global variables procedure local is begin select count(*) into cnt from msg; dbms_output.put_line('local: # of rows is '||cnt); insert into msg values ('New Record'); commit; end; begin delete from msg ; commit; insert into msg values ('Row 1'); local; select count(*) into cnt from msg; dbms_output.put_line('main: # of rows is '||cnt); rollback; local; insert into msg values ('Row 2'); commit; local; select count(*) into cnt from msg; dbms_output.put_line('main: # of rows is '||cnt); end;运行结果(注意打开serveroutput)local: # of rows is 1 -> 子程序local中可以’看到’主匿名块中的uncommitted记录main: # of rows is 2 -> 主匿名块可以’看到’2条记录(它们都是被local commit掉的)local: # of rows is 2 -> 子程序local首先’看到’2条记录,然后又commit了第三条记录local: # of rows is 4 -> 子程序local又’看到’了新增加的记录(它们都是被local commit掉的),然后又commit了第五条记录main: # of rows is 5 -> 主匿名块最后’看到’了所有的记录.从这个例子中,我们看到COMMIT和ROLLBACK的位置无论是在主匿名块中或者在子程序中,都会影响到整个当前事务.现在用AT改写一下匿名块中的procedure local:... procedure local is pragma AUTONOMOUS_TRANSACTION; begin...重新运行(注意打开serveroutput)local: # of rows is 0 -> 子程序local中无法可以’看到’主匿名块中的uncommitted记录 (因为它是独立的)main: # of rows is 2 -> 主匿名块可以’看到’2条记录,但只有一条是被commited.local: # of rows is 1 -> 子程序local中可以’看到’它前一次commit的记录,但是主匿名块中的记录已经被提前rollback了local: # of rows is 3 -> 子程序local 中可以’看到’3条记录包括主匿名块commit的记录main: # of rows is 4 ->主匿名块最后’看到’了所有的记录.很明显,AT是独立的,在它执行时,MT被暂停了. AT的COMMIT,ROLLBACK并不影响MT的执行.运用AT时,有一些注意事项,简单列举如下:1. 在匿名PL/SQL块中,只有顶级的匿名PL/SQL块可以被设为AT2. 如果AT试图访问被MT控制的资源,可能有deadlock发生.3. Package 不能被声明为AT,只有package所拥有的function和procedure 才能声明为AT4. AT程序必须以commit 或rollback结尾,否则会产生Oracle错误ORA-06519: active autonomous transaction detected and rolled back在程序开发时,如果充分运用AUTONOMOUS TRANSACTION的特性,一定能取得事倍功半的效果.
一大堆理论 begin if inserting then ----- elsif updating then ----- elsif deleting then ------ end if; end;
AFTER INSERT
ON ceo_compensation
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO ceo_comp_history
VALUES (:NEW.name,
:OLD.compensation, :NEW.compensation,
'AFTER INSERT', SYSDATE);
COMMIT;
END;
更多请查看帮助。
这是什么意思?能解释下吗?谢谢
AUTONOMOUS TRANSACTION(自治事务)的介绍:在基于低版本的ORACLE做一些项目的过程中,有时会遇到一些头疼的问题.,比如想在执行当前一个由多个DML组成的transaction(事务)时,为每一步DML记录一些信息到跟踪表中,由于事务的原子性,这些跟踪信息的提交将决定于主事务的commit或rollback. 这样一来写程序的难度就增大了, 程序员不得不把这些跟踪信息记录到类似数组的结构中,然后在主事务结束后把它们存入跟踪表.哎,真是麻烦!有没有一个简单的方法解决类似问题呢?ORACLE8i的AUTONOMOUS TRANSACTION(自治事务,以下AT)是一个很好的回答。AT 是由主事务(以下MT)调用但是独立于它的事务。在AT被调用执行时,MT被挂起,在AT内部,一系列的DML可以被执行并且commit或rollback.注意由于AT的独立性,它的commit和rollback并不影响MT的执行效果。在AT执行结束后,主事务获得控制权,又可以继续执行了。如何实现AT的定义呢?我们来看一下它的语法。其实非常简单。只需下列PL/SQL的声明部分加上PRAGMA AUTONOMOUS_TRANSACTION 就可以了。1. 顶级的匿名PL/SQL块2. Functions 或 Procedure(独立声明或声明在package中都可)3. SQL Object Type的方法4. 触发器。 比如: 在一个独立的procedure中声明ATCREATE OR REPLACE PROCEDURE Log_error(error_msg IN VARCHAR2(100))IS PRAGMA AUTONOMOUS_TRANSACTION;BEGIN Insert into Error_log values ( sysdate,error_msg); COMMIT;END;下面我们来看一个例子,(win2000 advanced server + oracle8.1.6 , connect as scott)建立一个表:create table msg (msg varchar2(120));首先,用普通的事务写个匿名PL/SQL块: declare cnt number := -1; --} Global variables procedure local is begin select count(*) into cnt from msg; dbms_output.put_line('local: # of rows is '||cnt); insert into msg values ('New Record'); commit; end; begin delete from msg ; commit; insert into msg values ('Row 1'); local; select count(*) into cnt from msg; dbms_output.put_line('main: # of rows is '||cnt); rollback; local; insert into msg values ('Row 2'); commit; local; select count(*) into cnt from msg; dbms_output.put_line('main: # of rows is '||cnt); end;运行结果(注意打开serveroutput)local: # of rows is 1 -> 子程序local中可以’看到’主匿名块中的uncommitted记录main: # of rows is 2 -> 主匿名块可以’看到’2条记录(它们都是被local commit掉的)local: # of rows is 2 -> 子程序local首先’看到’2条记录,然后又commit了第三条记录local: # of rows is 4 -> 子程序local又’看到’了新增加的记录(它们都是被local commit掉的),然后又commit了第五条记录main: # of rows is 5 -> 主匿名块最后’看到’了所有的记录.从这个例子中,我们看到COMMIT和ROLLBACK的位置无论是在主匿名块中或者在子程序中,都会影响到整个当前事务.现在用AT改写一下匿名块中的procedure local:... procedure local is pragma AUTONOMOUS_TRANSACTION; begin...重新运行(注意打开serveroutput)local: # of rows is 0 -> 子程序local中无法可以’看到’主匿名块中的uncommitted记录 (因为它是独立的)main: # of rows is 2 -> 主匿名块可以’看到’2条记录,但只有一条是被commited.local: # of rows is 1 -> 子程序local中可以’看到’它前一次commit的记录,但是主匿名块中的记录已经被提前rollback了local: # of rows is 3 -> 子程序local 中可以’看到’3条记录包括主匿名块commit的记录main: # of rows is 4 ->主匿名块最后’看到’了所有的记录.很明显,AT是独立的,在它执行时,MT被暂停了. AT的COMMIT,ROLLBACK并不影响MT的执行.运用AT时,有一些注意事项,简单列举如下:1. 在匿名PL/SQL块中,只有顶级的匿名PL/SQL块可以被设为AT2. 如果AT试图访问被MT控制的资源,可能有deadlock发生.3. Package 不能被声明为AT,只有package所拥有的function和procedure 才能声明为AT4. AT程序必须以commit 或rollback结尾,否则会产生Oracle错误ORA-06519: active autonomous transaction detected and rolled back在程序开发时,如果充分运用AUTONOMOUS TRANSACTION的特性,一定能取得事倍功半的效果.
begin
if inserting then
-----
elsif updating then
-----
elsif deleting then
------
end if;
end;