oracle触发器创建格式
Oracle 用户事件触发器
Oracle 用户事件触发器用户事件触发器是建立在模式级的操作上的触发器。
激活该类型触发器的用户事件包括:CREATE、ALTER、DROP、ANAL YZE、ASSOCIATE STATISTICS、DISASSOCIATE 、STA TISTICS、COMMENT、GRANT、REVOKE、RENAME、TRUNCA TE、LOGOFF、SUSPEND 和LOGON。
下面的示例将创建一个用户模式级触发器,以记录用户删除的数据库对象。
(1)以SCOTT身份连接到数据,并建立一个日志信息表。
SQL> create table droped_objects(2 object_name varchar2(30),3 object_type varchar2(30),4 dropped_on date);表已创建。
(2)创建用户事件触发器,以便记录用户删除的数据库对象。
SQL> create or replace trigger log_drop_trigger2 before drop on scott.schema3 begin4 insert into droped_objects values(5 ora_dict_obj_name,6 ora_dict_obj_type,7 sysdate);8 end;9 /触发器已创建在编写用户事件触发器时,经常会需要使用一些事件属性函数,例如,上面示例中的ORA_DICT_OBJ_NAME和ORA_DICT_OBJ_TYPE函数。
常用的事件属性函数如表7-1所示。
表7-1 事件属性函数事件属性函数说明ora_client_ip_address 返回客户端的IP地址ora_database_name 返回当前数据库名ora_des_encrypted_password 返回DES加密后的用户口令ora_dict_obj_name 返回DDL操作所对应的数据库对象名ora_dict_obj_name_list(name_list out ora_name_list_t) 返回在事件中被修改的对象名列表ora_dict_obj_owner 返回DDL操作所对应的对象的所有者名ora_dict_obj_owner_list(owner_list out ora_name_list_t) 返回在事件中被修改的对象的所有者列表ora_dict_obj_type 返回ddl操作所对应的数据库对象的类型ora_grantee(user_list out ora_name_list_t) 返回授权事件的授权者ora_instance_num 返回例程号ora_is_alter_column(column_name in varchar2) 检测特定列是否被修改ora_is_creating_nested_table 检测是否正在建立嵌套表ora_is_drop_column(column_name in varchar2) 检测特定列是否被删除ora_is_servererror(error_number) 检测是否返回了特定oracle错误ora_login_user 返回登录用户名ora_sysevent 返回触发器的系统事件名(3)删除SCOTT模式下的一些表或视图,测试触发器的运行情况。
跟我学Oracle数据库系统管理和实现——Oracle数据库DML触发器应用技术及应用实例
(2)触发器的程序代码示例
(3)注意代码中的someOneSequenceName是一个序列号的 名称,首先要定义出 (4)而someOneSequenceName.NEXTVAL获得序列号的下一 个唯一的序列值,因此如下的语句也就是把那个唯一的序 列值填写到 someOneTableName数据库表的ID字段。 “SELECT someOneSequenceName.NEXTVAL INTO :NEW.ID FROM DUAL;”
(3)利用下面的代码触发该触发器的执行 (4)在输出控制台中出现警告信息。
(5)对前面的示例也可以采用可视化方式实现
6、语句级触发器应用示例二 (1)为什么要应用触发器实现此功能
下面的触发器示例实现在插入数据库表数据时自动为 该表中的ID字段赋值,从而可以自动生成ID字段的值。
之所以应用触发器实现此功能,是因为在Oracle数据 库系统中不直接支持自动递增的数据列,因此需要创建出 一个序列SEQUENCE。
Oracle 数据库 DML触发器 应用技术及应用实例
1、DML触发器是定义在一个表或视图(针对某个数据库表 的视图)上的触发器
(1)什么是DML触发器
DML触发器是指基于DML操作所建立的触发器,DML触发 器是最常用的触发器,一旦建立了DML触发器后,如果发生 了DML操作(insert、delete或update等)就会执行相应的 触发器所指定的程序代码。
由于CUSTOMER_INFO表和CONTRACT_INFO数据库表产生 一对多的关联关系,当删除一个客户信息时,对应的合同 信息也级联删除。
(2)代码示例
(2)创建行级触发器的语法 格式
oracle触发器执行顺序
oracle触发器执行顺序2010-9-13表:emp--创建包变量CREATE PACKAGE EMP_PACKAGE lSold_sum NUMBER;--存放原来薪水总额new_sum NUMBER;--存放新的薪水总额test1 number;--before upate 对应值1test2 number;--before update each row 对应值2test3 number;--after update each row 对应值3test4 number;--after update 对应值4END;注:每个触发器执行都会对应上面变量进行赋值业务规则1:给员工加薪时,要扣税,扣税的规则是,原来薪水在5000或以上的扣除总薪水的10%,小于5000的扣除总薪水的20%业务规则2:如果目前全体员工的总薪水大于或等于15000,则不能加薪了;如果总薪水小于10000,则不能减薪了。
一.不同类型触发器(行级和语句)1.before触发器--原来总薪水总额(语句)CREATE OR REPLACE TRIGGER before_update_salaryBEFORE UPDATE ON EMPbeginSELECT SUM(salary)INTO EMP_PACKAGE.old_sum FROM EMP;EMP_PACKAGE.TEST1:=1;/*RAISE_APPLICATION_ERROR(-20003,nvl(EMP_PACKAGE.test2,0));*/end;--更改每行数据(行级)CREATE OR REPLACE TRIGGER before_add_salaryBEFORE UPDATE ON EMPFOR EACH rowBEGINif:new.salary>:OLD.salary THEN --加薪if:old.salary <5000THEN:NEW.salary :=:NEW.salary*0.8;RAISE_APPLICATION_ERROR(-20004,nvl(EMP_PACKAGE.test1,0));EMP_PACKAGE.TEST2:=2;ELSE:NEW.salary :=:NEW.salary*0.9;RAISE_APPLICATION_ERROR(-20005,nvl(EMP_PACKAGE.test1,0));EMP_PACKAGE.TEST2:=2;END IF;END IF;END;---现在对empno =5的员工薪水改为8000,执行得到以下报错(屏蔽before_update_salary报错)--现在对empno =5的员工薪水改为8000,执行得到以下报错(屏蔽before_add_salary报错)2.after触发器--判断员工新薪水(行级)create or replace trigger after_update_salary_rowafter UPDATE ON EMPfor each rowbeginif:new.salary>:OLD.salary THENif:new.salary <5000THEN/*RAISE_APPLICATION_ERROR(-20006,nvl(EMP_PACKAGE.test4,0));*/EMP_PACKAGE.test3:=3;ELSE/* RAISE_APPLICATION_ERROR(-20007,nvl(EMP_PACKAGE.test4,0));*/ EMP_PACKAGE.test3:=3;END IF;END IF;end;----判断是否可以加薪或减薪(语句)create or replace trigger after_update_salaryafter UPDATE ON EMPbeginSELECT SUM(salary)INTO EMP_PACKAGE.new_sum FROM EMP;if EMP_PACKAGE.new_sum> EMP_PACKAGE.old_sum thenif EMP_PACKAGE.old_sum>=15000thenRAISE_APPLICATION_ERROR(-20008,nvl(EMP_PACKAGE.test3,0));EMP_PACKAGE.test4:=4;end if;elseif EMP_PACKAGE.old_sum<10000thenRAISE_APPLICATION_ERROR(-20009,nvl(EMP_PACKAGE.test3,0));EMP_PACKAGE.test4:=4;end if;end if;end;--现在对empno =5的员工薪水改为8000,执行得到以下报错(屏蔽after_update_salary_row 报错)--现在对empno =5的员工薪水改为8000,执行得到以下报错(屏蔽after_update_salary报错)综合以上结果:oracle 一个表上的多个触发器的执行顺序如下:before 语句trigger->before 行级trigger->after 行级trigger->after 语句trigg er。
Oracle触发器trigger详解
Oracle触发器trigger详解触发器相关概念及语法,供⼤家参考,具体内容如下概述本篇博⽂中主要探讨以下内容:什么是触发器触发器的应⽤场景触发器的语法触发器的类型案例数据:触发器的概念和第⼀个触发器数据库触发器是⼀个与表相关联的,存储的PL/SQL 语句。
每当⼀个特定的数据操作语句(insert update delete)在指定的表上发出时,Oracle⾃动执⾏触发器中定义的语句序列。
举个简单的例⼦:当员⼯表中新增⼀条记录后,⾃动打印“成功插⼊新员⼯”create or replace trigger insertStaffHintafter insert on xgj_testfor each rowdeclare-- local variables herebegindbms_output.put_line('新增员⼯成功');end insertStaffHint;触发器的应⽤场景复杂的安全性检查数据的确认数据库审计数据的备份和审计触发器的语法CREATE [OR REPLACE] TRIGGER trigger_name{BEFORE | AFTER }{INSERT | DELETE | UPDATE [OF column [, column …]]}[OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...]ON [schema.]table_name | [schema.]view_name[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}][FOR EACH ROW ][WHEN condition]PL/SQL_BLOCK | CALL procedure_name;其中:BEFORE 和AFTER指出触发器的触发时序分别为前触发和后触发⽅式,前触发是在执⾏触发事件之前触发当前所创建的触发器,后触发是在执⾏触发事件之后触发当前所创建的触发器。
Oracle数据库之PLSQL触发器
Oracle数据库之PLSQL触发器Oracle数据库之PL/SQL触发器1. 介绍触发器(trigger)是提供给程序员和数据分析员来保证数据完整性的⼀种⽅法,它是与表事件相关的特殊的存储过程,它的执⾏不是由程序调⽤,也不是⼿⼯启动,⽽是由事件来触发,⽐如当对⼀个表进⾏操作(insert,delete,update)时就会激活它执⾏。
触发器经常⽤于加强数据的完整性约束和业务规则等。
触发器有三种类型,分别是:DML触发器、替代触发器和系统触发器。
DML触发器顾名思义,DML触发器是由DML语句触发的。
例如数据库的INSERT、UPDATE、DELETE操作都可以触发该类型的触发器。
它们可以在这些语句之前或之后触发,或者在⾏级上触发(就是说对于每个受影响的⾏都触发⼀次)。
替代触发器替代触发器只能使⽤在视图上,与DML不同的是,DML触发器是运⾏在DML之外的,⽽替代触发器是代替激发它的DML语句运⾏。
替代触发器是⾏触发器。
系统触发器这种触发器是发⽣在如数据库启动或关闭等系统事件时,不是在执⾏DML语句时发⽣,当然也可以在DDL时触发。
触发器功能强⼤,轻松可靠地实现许多复杂的功能,但是我们也应该慎⽤。
为什么⼜要慎⽤呢?触发器本⾝没有过错,但如果我们滥⽤,会造成数据库及应⽤程序的维护困难。
在数据库操作中,我们可以通过关系、触发器、存储过程、应⽤程序等来实现数据操作,同时约束、缺省值也是保证数据完整性的重要保障。
如果我们对触发器过分的依赖,势必影响数据库的结构,同时增加了维护的复杂程度。
2. 触发器组成触发器主要由以下⼏个要素组成:1. 触发事件:引起触发器被触发的事件。
2. 触发时间:触发器是在触发事件发⽣之前(BEFORE)还是之后(AFTER)触发,也就是触发事件和该触发器的操作顺序。
3. 触发操作:触发器被触发之后的⽬的和意图,是触发器本⾝要做的事情。
4. 触发对象:包括表、视图、模式、数据库。
oracle 触发器的实例
oracle 触发器的实例触发器使用教程和命名规范目录触发器使用教程和命名规范 11,触发器简介 12,触发器示例 23,触发器语法和功能 34,例一:行级触发器之一 45,例二:行级触发器之二 46,例三:INSTEAD OF触发器 67,例四:语句级触发器之一 88,例五:语句级触发器之二 99,例六:用包封装触发器代码 1010,触发器命名规范 111,触发器简介触发器(Trigger)是数据库对象的一种,编码方式类似存储过程,与某张表(Table)相关联,当有DML语句对表进行操作时,可以引起触发器的执行,达到对插入记录一致性,正确性和规范性控制的目的。
在当年C/S时代盛行的时候,由于客户端直接连接数据库,能保证数据库一致性的只有数据库本身,此时主键(Primary Key),外键(Foreign Key),约束(Constraint)和触发器成为必要的控制机制。
而触发器的实现比较灵活,可编程性强,自然成为了最流行的控制机制。
到了B/S时代,发展成4层架构,客户端不再能直接访问数据库,只有中间件才可以访问数据库。
要控制数据库的一致性,既可以在中间件里控制,也可以在数据库端控制。
很多的青睐Java的开发者,随之将数据库当成一个黑盒,把大多数的数据控制工作放在了Servlet中执行。
这样做,不需要了解太多的数据库知识,也减少了数据库编程的复杂性,但同时增加了Servlet编程的工作量。
从架构设计来看,中间件的功能是检查业务正确性和执行业务逻辑,如果把数据的一致性检查放到中间件去做,需要在所有涉及到数据写入的地方进行数据一致性检查。
由于数据库访问相对于中间件来说是远程调用,要编写统一的数据一致性检查代码并非易事,一般采用在多个地方的增加类似的检查步骤。
一旦一致性检查过程发生调整,势必导致多个地方的修改,不仅增加工作量,而且无法保证每个检查步骤的正确性。
触发器的应用,应该放在关键的,多方发起的,高频访问的数据表上,过多使用触发器,会增加数据库负担,降低数据库性能。
oracle序列和触发器
oracle序列和触发器1、创建表t1 :create table t1 (id number,name nvarchar(8));2、创建序列:CREATE SEQUENCE t1_id INCREMENT BY 1 START WITH 1 MAXV ALUE 1.0E28 MINV ALUE 1 NOCYCLE CACHE 20 NOORDER3. 创建触发器:CREATE TRIGGER tig_insert_t1BEFORE INSERT ON "YINZQ"."T1"beginif (:new.id is null) thenselect t1_id.nextval into :new.id from dual; //其中的:new.id 指的是t1表中新行的列end if;end;Oracle触发器语法触发器是特定事件出现的时候,自动执行的代码块。
类似于存储过程,触发器与存储过程的区别在于:存储过程是由用户或应用程序显式调用的,而触发器是不能被直接调用的。
功能:1、允许/限制对表的修改2、自动生成派生列,比如自增字段3、强制数据一致性4、提供审计和日志记录5、防止无效的事务处理6、启用复杂的业务逻辑触发器触发时间有两种:after和before。
1、触发器的语法:CREATE [OR REPLACE] TIGGER触发器名触发时间触发事件ON表名[FOR EACH ROW]BEGINpl/sql语句END其中:触发器名:触发器对象的名称。
由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。
触发时间:指明触发器何时执行,该值可取:before---表示在数据库动作之前触发器执行;after---表示在数据库动作之后出发器执行。
触发事件:指明哪些数据库动作会触发此触发器:insert:数据库插入会触发此触发器;让oracle实现自增字段先建序列,然后建立一个触发器实现!cata0是表名,cata0_id是需要自增的字段!CREATE SEQUENCE SEQ_cata0INCREMENT BY 1START WITH 1MAXV ALUE 9999999CREATE TRIGGER TRG_cata0 BEFOREINSERT ON cata0FOR EACH ROW beginSELECT SEQ_cata0.NEXTV ALINTO :NEW.cata0_IDfrom DUAL;End TRG_cata0;/****@PARAM STNAME 不要创建序列的表,多个表则以“,”隔开**/CREATE OR REPLACE PROCEDURE PROC_CREATE_SEQ_TRIG(STNAME IN V ARCHAR2)ASSTRSQL VARCHAR2(4000);TABLENAME V ARCHAR2(50);PID V ARC ......。
Oracle存储过程和触发器基本操作
南华大学计算机科学与技术学院实验报告(2012~2013 学年度第二学期)课程名称Oracle高级数据库开发设计实验名称存储过程与触发器基本操作姓名学号专业班级地点教师前提表脚本:create table S_RZ0122 (Sno varchar2(11) primary key,Sname varchar2(20) not null,Ssex varchar(2) not null ,Sage number(2) not null,Sdept varchar(20) not null)create table C_RZ0122(Cno varchar2(20) primary key,Cname varchar2(20) not null ,Ccredit number(2) not null)create table SC_RZ0122(Sno varchar2(11) not null,Cno varchar2(20) not null,Score number(3) ,primary key(Sno ,Cno),foreign key(Sno) references S_RZ0122(Sno),foreign key(Cno) references C_RZ0122(Cno))INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0811101,'李勇','男',21,'计算机系')INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0811102,'刘晨','男',20,'计算机系')INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0811103,'王敏','女',20,'计算机系')INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0811104,'张小红','女',19,'计算机系')INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0821101,'张立','男',20,'信息管理系')INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0821102,'吴宾','女',19,'信息管理系')INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0821103,'张海','男',20,'信息管理系')INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0831101,'钱小平','女',21,'通信工程系')INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0831102,'王大力','男',20,'通信工程系')INSERT INTO S_RZ0122 (Sno ,Sname,Ssex,Sage ,Sdept) V ALUES(0831103,'张珊珊','女',19,'通信工程系')---增加课程信息脚本:---insert allINSERT INTO C_RZ0122 (Cno ,Cname ,Ccredit ) V ALUES ('C001','高等数学',4) INSERT INTO C_RZ0122 (Cno ,Cname ,Ccredit ) V ALUES ('C002','大学英语',3) INSERT INTO C_RZ0122 (Cno ,Cname ,Ccredit ) V ALUES ('C003','大学英语',3) INSERT INTO C_RZ0122 (Cno ,Cname ,Ccredit ) V ALUES ('C004','计算机文化学',2) INSERT INTO C_RZ0122 (Cno ,Cname ,Ccredit ) V ALUES ('C005','VB',2)INSERT INTO C_RZ0122 (Cno ,Cname ,Ccredit ) V ALUES ('C006','数据库基础',4) INSERT INTO C_RZ0122 (Cno ,Cname ,Ccredit ) V ALUES ('C007','数据结构',4) INSERT INTO C_RZ0122 (Cno ,Cname ,Ccredit ) V ALUES ('C008','计算机网络',4) select * from C_RZ0122;---增加关联学生和课程信息脚本:---INSERT ALLINSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0811101,'C001',96)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0811101,'C002',80)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0811101,'C003',84)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0811101,'C005',62)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0811102,'C001',92)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0811102,'C002',90)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0811102,'C004',84)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0821102,'C001',76)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0821102,'C004',85)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0821102,'C005',73)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0821102,'C007',0)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0821103,'C001',50)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0821103,'C004',80)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0831101,'C001',50)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0831101,'C004',80)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0831102,'C007',0)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0831103,'C004',78)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0831103,'C005',65)INSERT INTO SC_RZ0122(Sno,Cno,Score) V ALUES (0831103,'C007',0)select Sno,Cno,Score from SC_RZ0122;一.实验题目存储过程与触发器基本操作二.实验要求掌握对存储过程和触发器的创建、修改等基本操作。
oracle触发器-解决mutating table的问题
Oracle触发器mutating table问题解决方案一、问题描述Oracle触发器是特定事件出现的时候,自动执行的代码块。
但在使用过程中,往往遇到如下需求:1、在触发器执行时,使用DML语言操作触发器的基础表,完成更新、插入或删除操作;2、触发器对于父子表,即有外键关联的表的相关操作;或者说trigger访问了自身上的表。
在以上两种情况下,依据Oracle的事务处理规则,通常产生如下错误:ORA-04091。
该错误解释为:当前的trigger下的事物,access(执行)了一个mutating table(冲突的表)。
一个简单的例子拿oracle的示例表emp和dept来做这个试验。
dept的表结构如下:emp表结构如下:emp和dept是一对父子表,关联column为DEPTNO。
接下来创建1个table:emp_log 和1个语句级trigger: emp_del_trg。
取一个最简单的业务功能,emp_del_trg的作用就是当表emp记录被删除的时候,触发器将删除的记录的EMPNO,DNAME和删除时间写入到emp_log中,当子表依赖的父表相关记录删除的时候,emp_log不做处理。
表emp_log的结构如下:触发器trigger代码如下:来看看这个触发器是否能正常工作,首先删除emp的记录。
看似trigger工作正常,删除dept的记录呢?问题分析:ORA-04091错误如约而至。
不难解释,因为父子表指定了级联删除,删除dept的记录从而引起删除emp表上的相应数据,然后触发了emp_del_trg,由于trigger里有对dept的访问,对当前事务说,dept就是一个mutating table,这是不被允许的。
如何来解决这个问题而实现这个简单的业务逻辑功能呢?当然,从表结构逻辑设计上来讲,可以将dept表上的dname字段add到emp表,或者不要显式的指定references,用程序来维护数据的完整性和约束,然后调整业务代码.最直接的方法,在trigger中声明一个ora-04091的exception,对此异常不做处理,也可完成目的。
oracle 触发器(trigger)
触发器的使用1触发器资料来源:《/view/71791.htm?fr=ala0_1_1》触发器(trigger)是个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作(insert,delete,update)时就会激活它执行。
触发器经常用于加强数据的完整性约束和业务规则等。
触发器可以从DBA_TRIGG ERS ,USER_TRIGGERS 数据字典中查到。
1.1 数据库领域名词触发器可以查询其他表,而且可以包含复杂的SQL语句。
它们主要用于强制服从复杂的业务规则或要求。
例如:您可以根据客户当前的帐户状态,控制是否允许插入新订单。
触发器也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。
然而,强制引用完整性的最好方法是在相关表中定义主键和外键约束。
如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。
1.2 创建触发器的SQL语法DELIMITER |CREATE TRIGGER `<databaseName>`.`<triggerName>`< [ BEFORE | AFTER ] > < [ INSERT | UPDATE | DELETE ] >ON <tableName>FOR EACH ROWBEGIN--do somethingEND |1.3 触发器的优点触发器可通过数据库中的相关表实现级联更改;不过,通过级联引用完整性约束可以更有效地执行这些更改。
触发器可以强制比用CHECK 约束定义的约束更为复杂的约束。
与CHECK 约束不同,触发器可以引用其它表中的列。
例如,触发器可以使用另一个表中的SELECT 比较插入或更新的数据,以及执行其它操作,如修改数据或显示用户定义错误信息。
触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。
Oracle 语句级触发器
Oracle 语句级触发器如果在创建触发器时未使用FOR EACH ROW子句,则创建的触发器为语句级触发器。
语句级触发器在被触发后只执行一次,而不管这一操作会影响到数据库中多少行记录。
下面是一个简单的语句级触发器,该触发器将记录用户对SCOTT.EMP表的操作。
(1)以SCOTT身份连接到数据库,建立一个日志信息表EMP_LOG,用于存储用户对表的操作。
SQL> connect scott/tiger已连接。
SQL> create table emp_log(2 who varchar2(30),3 when date);表已创建。
(2)在EMP表上创建语句级触发器,将用户对EMP表进行操作记录到EMP_LOG表中。
SQL> create or replace trigger emp_op2 before insert or update or delete3 on emp4 begin5 insert into emp_log(who,when)6 values(user,sysdate);7 end emp_op;8 /触发器已创建(3)更新EMP表,增加员工10%的薪金,确认触发器是否能够正常运行。
SQL> update emp2 set sal=sal*1.1;已更新15行。
SQL> select * from emp_log;WHO WHEN------------------------------ --------------SCOTT 01-5月-08从上面的查询结果可以看出,触发器准确记录了用户在何时对表进行了操作。
另外,还有一点需要注意,上面的UPDA TE语句更新了多行数据,但而触发器向表EMP_LOG中仅添加了一行记录,这就是语句级触发器的特点。
在上面的EMP_OP触发器中使用了多个触发事件,这就需要考虑一个问题,如何确定哪个语句导致了触发器的激活?为了确定触发事件可以使用条件谓词,条件谓词由一个关键字IF和谓词INSERTING、UPDATING和DELETING构成。
Oracle_EBS_Form_触发器学习大全
Oracle EBS Form Trigger学习大全打开,关闭,创建,更新记录的trigger次序PRE-……在进入一个form,或是导航到一个新的block时触发,PRE-……系列的触发器一般是在WHEN-NEW-……-INSTANCE系列之前,它们如果失败了的话,就不能成功导航到下一个对象了,只能留在当前的位置。
在这些触发器里可以设置一些判断条件来限制是否可以导航到新的位置。
WHEN-NEW-……-INSTANCE这一类的trigger都是当鼠标光标每次落到一个新的block,record,item上时触发的,而且就算失败了,也不会发生什么错误。
但是when-new-form-instance,只有当form 启动时,光标导航到第一个导航块的第一个导航item时触发,如果一个应用有多个form,当光标在各个form之间转换时,并不会触发它。
POST-TEXT-ITEM和WHEN-VALIDATE-ITEMPost-text-item的触发点:当输入的光标从一个Text-Item 转到其它item,可以用它来改变item的值,而when-Validate-item虽然也是在离开前触发,但是作用不同,Post-Text-Item本身是没有验证的,when-Validate-item可以用来补充一些验证(除了form本身的验证),但是当form验证成功以后,会把item标志为…valid‟,而不会再去验证了,如果这时我们再去修改它的值,那么就有可能会把无效的值导入到数据库。
在创建和更新一条记录时,先触发when-Validate-item,再触发Post-Text-Item,然后是when-Validate-record。
POST-……系列的都是离开当前的block,record,item时触发的WHEN-WINDOW-ACTIVATED做原材料属性修改平台时,第一次使用这个触发器,用来从另一个window返回时,刷新当前window,代码写在了这个触发器里。
oracle 触发器case写法
Oracle触发器是一种用于在数据库发生特定事件时自动执行某些操作的数据库对象。
触发器可以用于在数据插入、更新或删除时执行特定的逻辑,以确保数据的完整性和一致性。
在Oracle数据库中,触发器是一种强大的工具,可以帮助数据库开发人员实现复杂的业务逻辑和数据处理需求。
在使用Oracle触发器时,我们需要根据具体的业务需求来编写相应的触发器,以确保触发器能够正确地响应数据库中发生的事件,并执行相应的操作。
在编写Oracle触发器时,我们需要遵循一定的写法和规范,以确保触发器的可靠性和可维护性。
以下是关于Oracle触发器编写的一些常见的写法和注意事项:1. 指定触发器的事件类型和触发时机在编写Oracle触发器时,首先需要明确触发器要响应的事件类型和触发时机。
Oracle触发器可以在数据插入(INSERT)、更新(UPDATE)或删除(DELETE)时触发,我们需要根据具体的业务需求来选择合适的事件类型和触发时机。
2. 触发器的创建和定义在指定了触发器要响应的事件类型和触发时机之后,我们需要使用CREATE TRIGGER语句来创建和定义触发器。
在触发器的定义中,需要指定触发器的名称、所属的表名、触发时机以及触发器的逻辑。
3. 触发器的语法和逻辑在编写Oracle触发器的逻辑时,需要使用PL/SQL语言来实现触发器的逻辑。
我们可以在触发器中编写适当的PL/SQL代码来执行数据处理、业务逻辑或其他操作。
在编写触发器的逻辑时,需要确保逻辑的正确性和可靠性,以确保触发器能够正确地执行所需的操作。
4. 考虑触发器的性能和效率在编写Oracle触发器时,需要考虑触发器的性能和效率。
触发器的逻辑和操作可能会对数据库的性能产生影响,我们需要审慎地编写触发器的逻辑,以确保触发器能够在不影响数据库性能的情况下正确地执行所需的操作。
5. 测试和调试触发器在编写Oracle触发器之后,需要对触发器进行测试和调试,以确保触发器能够正确地响应所需的事件,并执行相应的操作。
oracle触发器delete写法
概述:本文将针对Oracle数据库中触发器的delete写法展开讨论,通过逐步介绍触发器的基本概念和使用方法,深入探究delete触发器的写法以及相关注意事项。
文章将以从简到繁的方式,帮助读者全面理解delete触发器的实现原理和应用技巧。
一、触发器的基本概念和使用方法1.1 触发器的概念和作用在Oracle数据库中,触发器是一种特殊的存储过程,它是与表相关联的数据库对象,当表上出现特定的事件,比如insert、update或delete操作时,触发器会自动执行相应的动作。
1.2 触发器的创建和语法在创建触发器时,需要指定触发的事件(insert、update或delete)、触发的时机(before或after)以及触发的操作(行级触发器或语句级触发器)。
触发器的语法如下:```sqlCREATE [OR REPLACE] TRIGGER trigger_nameBEFORE/AFTER INSERT/UPDATE/DELETEON table_name[FOR EACH ROW]BEGIN-- 触发器执行的动作END;```1.3 触发器的应用场景触发器通常用于实现数据的自动化维护、约束的强制执行等应用场景。
delete触发器作为其中的一种,可以在数据删除操作时执行一系列特定的逻辑处理,保证数据的完整性和一致性。
二、delete触发器的写法及注意事项2.1 delete触发器的基本写法在创建delete触发器时,需要注意触发时机、执行动作和逻辑处理。
delete触发器通常在数据删除之前或之后执行,可以用于记录日志、更新相关数据等操作。
以下是delete触发器的基本写法示例:```sqlCREATE OR REPLACE TRIGGER delete_triggerBEFORE DELETEON table_nameFOR EACH ROWBEGIN-- 执行相关逻辑处理END;```2.2 delete触发器的注意事项在编写delete触发器时,需要注意以下几点:- 触发时机的选择:根据业务需求和数据完整性考虑,选择合适的触发时机(before或after)。
Oracle触发器详解
Oracle触发器详解一、触发器概述触发器是特定事件出现的时候,自动执行的代码块。
类似于存储过程,但是用户不能直接调用他们。
功能:1、 允许/限制对表的修改2、 自动生成派生列,比如自增字段3、 强制数据一致性4、 提供审计和日志记录5、 防止无效的事务处理6、 启用复杂的业务逻辑触发器触发时间有两种:after和before。
1、触发器的语法:CREATE [OR REPLACE] TIGGER触发器名 触发时间 触发事件ON表名[FOR EACH ROW]BEGINpl/sql语句END其中:触发器名:触发器对象的名称。
由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。
触发时间:指明触发器何时执行,该值可取:before---表示在数据库动作之前触发器执行;after---表示在数据库动作之后出发器执行。
触发事件:指明哪些数据库动作会触发此触发器:insert:数据库插入会触发此触发器;update:数据库修改会触发此触发器;delete:数据库删除会触发此触发器。
表名:数据库触发器所在的表。
for each row:对表的每一行触发器执行一次。
如果没有这一选项,则只对整个表执行一次。
触发器的组成部分:1、 触发器名称2、 触发语句3、 触发器限制4、 触发操作触发器类型:1、 语句触发器2、 行触发器3、 INSTEAD OF 触发器4、 系统条件触发器5、 用户事件触发器注释:before和after:指在事件发生之前或之后激活触发器。
instead of:如果使用此子句,表示可以执行触发器代码来代替导致触发器调用的事件。
insert、 delete和update:指定构成触发器事件的数据操纵类型,update还可以制定列的列表。
此类触发器用的不多,经常用于视图,不做重点。
table_or_view_name:指要创建触发器的表或视图的名称。
for each row:指定是否对受影响的每行都执行触发器,即行级触发器,如果不使用此子句,则为语句级触发器。
oracle_form_常用Trigger的触发时机-执行顺序
常用Trigger的触发时机●Form Level:●Block Level:Item Level:常见的Trigger触发顺序触发器执行顺序:1.当打开FORM时:(1)PRE-FORM(2)PRE-BLOCK(BLOCK级)(3)WHEN-NEW-FORM-INSTANCE(4)WHEN-NEW-BLOCK-INSTANCE(5)WHEN-NEW-RECORD-INSTANCE(6)WHEN-NEW-ITEM-INSTANCE2.当填写一行记录完成后,光标移动到下一条记录的时候:(1)WHEN-VALIDATE-RECORD(只将填写的记录与数据库中已存在的记录作唯一性的验证,如果只是页面上的数据重复而数据库中没有与其重复的值则不会报错.)(2)WHEN-NEW-RECORD-INSTANCE(3)WHEN-NEW-ITEM-INSTANCE3.当点击“保存”时(1)WHEN-VALIDATE-RECORD(将页面上的所有数据提交到数据库,若页面上有重复的数据,则提交第一次时成功但只是将数据先写到数据库中一类似临时表的地方,在提交第二条重复记录的时候报错,执行事务回滚,原来执行成功的指令也将被撤消)(2)PRE-INSERT(3)ON-INSERT(4)POST-INSERT(5)POST-FORMS-COMMIT(6)PRE-BLOCK(BLOCK级)(7)KEY-COMMIT(8)WHEN-NEW-ITEM-INSTANCE4.当光标移动到当前数据块中已经显示的行上时:(1)WHEN-REMOVE-RECORD(2)WHEN-NEW-RECORD-INSTANCE(3)WHEN-NEW-ITEM-INSTANCE当在该行上的不同ITEM移动时:(4)WHEN-NEW-ITEM-INSTANCE5.当要进行修改时(在记录中的某个项上进行了修改时):(1)ON-LOCK6.在修改完成后进行保存时:(1)WHEN-VALIDATE-RECORD(2)PRE-UPDATE(3)ON-UPDATE(4)POST-FORMS-COMMIT(5)PRE-BLOCK(BLOCK级)(6)KEY-COMMIT(7)WHEN-NEW-ITEM-INSTANCE7.删除一条记录时:(1)ON-LOCK(2)WHEN-REMOVE-RECORD(3)KEY-DELREC(4)WHEN-NEW-RECORD-INSTANCE(5)WHEN-NEW-ITEM-INSTANCE8.F11查询过程:(1)WHEN-CLEAR-BLOCK(2)WHEN-NEW-RECORD-INSTANCE(3)WHEN-NEW-ITEM-INSTANCE在输入查询条件后点CTRL+F11:(4)PRE-QUERY(5)WHEN-CLEAR-BLOCK(6)POST-QUERY(7)WHEN-NEW-RECORD-INSTANCE(8)WHEN-NEW-ITEM-INSTANCE9.CRRL+F11:(1)WHEN-CLEAR-BLOCK(2)PRE-QUERY(3)WHEN-CLEAR-BLOCK(4)POST-QUERY(每查一条记录,触发一次)(5)WHEN-NEW-RECORD-INSTANCE(6)WHEN-NEW-ITEM-INSTANCE10.从查询状态(F11)转为输入状态(F4)时:(1)WHEN-CLEAR-BLOCK(2)KEY-EXIT(3)WHEN-NEW-RECORD-INSTANCE(4)WHEN-NEW-ITEM-INSTANCE11.手电筒查询过程:(1)QUERY_FIND(BLOCK级)输入查询条件后,点击“查询”按钮:(2)WHEN-CLEAR-BLOCK(3)PRE-QUERY(4)WHEN-CLEAR-BLOCK(5)POST-QUERY(6)WHEN-NEW-RECORD-INSTANCE(7)WHEN-NEW-ITEM-INSTANCE12.点击“New”时:(1)WHEN-NEW-RECORD-INSTANCE(2)WHEN-NEW-ITEM-INSTANCE13.点击“EditField”时:(1)KEY-EDIT14.点击“WindowHelp”时:(1)KEY-HELP15.点击“ClearRecord”时:(1)WHEN-REMOVE-RECORD(2)POST-QUERY(3)WHEN-NEW-RECORD-INSTANCE(4)WHEN-NEW-ITEM-INSTANCE16.点击F4关闭时:(1)KEY-EXIT(2)POST-FORM17.点击“CloseForm”按钮关闭时:(1)KEY-EXIT(2)POST-FORM18.点击“Translations”按钮时:(1)TRANSLATIONS19.点击小叉号关闭时:(1)WHEN-WINDOW-CLOSED(2)CLOSE-WINDOW(3)KEY-EXIT(4)POST-FORM20.选中LOV列表:(1)KEY-LISTVAL(2)WHEN-NEW-ITEM-INSTANCE21.选中记录前面的小条时:(1)WHEN-NEW-RECORD-INSTANCE(2)WHEN-NEW-ITEM-INSTANCE(数据项级)(3)WHEN-NEW-ITEM-INSTANCE22.光标上下移动时:(1)WHEN-NEW-RECORD-INSTANCE(2)WHEN-NEW-ITEM-INSTANCE。
plsql触发器写法
plsql触发器写法PL/SQL触发器是一种特殊的存储过程,它在数据库中的表上自动执行。
当在表上执行特定的操作时,触发器会自动触发并执行相应的代码。
下面是PL/SQL触发器的详细创作步骤:1. 创建触发器使用CREATE TRIGGER语句创建触发器。
语法如下:CREATE [OR REPLACE] TRIGGER trigger_name{BEFORE | AFTER} {INSERT | UPDATE | DELETE}ON table_name[FOR EACH ROW][WHEN condition]DECLARE-- 触发器代码BEGIN-- 触发器代码END;其中,trigger_name是触发器的名称,table_name是触发器所在的表名,BEFORE 或AFTER指定触发器在执行操作之前或之后执行,INSERT、UPDATE或DELETE 指定触发器在执行相应操作时触发,FOR EACH ROW指定触发器对每一行数据都执行,WHEN condition是可选的,用于指定触发器执行的条件。
2. 编写触发器代码在DECLARE和BEGIN-END之间编写触发器代码。
触发器代码可以包括PL/SQL语句、SQL语句和存储过程调用等。
例如,以下是一个简单的触发器代码,用于在插入数据时自动更新另一个表的数据:DECLAREv_count NUMBER;BEGINSELECT COUNT(*) INTO v_count FROM table_name;UPDATE other_table SET count = v_count;END;3. 测试触发器在表上执行相应的操作,触发器会自动执行相应的代码。
可以使用SELECT语句检查触发器是否按预期工作。
4. 修改或删除触发器可以使用ALTER TRIGGER语句修改触发器,使用DROP TRIGGER语句删除触发器。
例如,以下是修改触发器的语法:ALTER TRIGGER trigger_name{ENABLE | DISABLE};其中,ENABLE或DISABLE用于启用或禁用触发器。
oracle触发器加条件判断
⽬录1.2.3.1.2.3. oracle触发器加条件判断oracle触发器加条件判断,如果某个字段,isnode=0,那么不执⾏下⾯的⽅法,数据如下:create or replace trigger tr_basestation_insert_empbefore insert on BJLT.BASESTATIONREFERENCING NEW AS new_val OLD AS old_val --在这⾥设置名字,然后可引⽤新值,旧值for each rowwhen (new_val.isnode =0)declare--local variables herebegininsert into BSMS.BS_INFO@TOBSMS_BETTERY_(INFOID, INFONAME, GROUPID, ADDRESS, BUILDDATE, MAINTENANCER, TEL, TEMPERATURE, RECTIFIERCUR, OUTVOL, CREATETIME, SORTID, ONEOFFVOL, TWOOFFVOL, ISNODE, NODENUM, ONOFFPOWER, ONOFFPOWERMODEL,POWERA, POWERB, POWERC, POWEROUT, POWERACUR, POWERBCUR, POWERCCUR, POWERAVOL, POWERBVOL,POWERCVOL, DOOROPEN, HS, YANGAN, SHUIJIN, HONGWAI, KONGTIAO, VERID)values ('1','1','8a82fcd4-eba9-4f83-82d6-8ded897f3f10','1',sysdate,'1','1',0,'1',1,sysdate,1,1,1,1,1,'1','1',-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1,-1,1);end;参考⾃:/weiwenhp/article/details/9179891trigger和procedure,function类似,只不过它不能被显⽰调⽤,只能被某个事件触发然后oracle⾃动去调⽤.常⽤的⼀般是针对⼀个表或视图创建⼀个trigger,然后对表或视图做某些操作时触发trigger.当然除此之外还有,schema,database级别的 trigger.什么样的操作触发trigger常见的是DML(insert,update,delete) , DDL(create,alter,drop)语句.不常见的是schema级别trigger在session连接或断开时触发.database级别trigger在系统启动或退出时触发.你可能很容易发现如果是select查询操作就没法⽤到trigger,⽽有时可能我们想监测谁查看了⼀些敏感信息,此时只能⽤到⼀个叫FGA的东东,可以创建⼀个审计策略(可以看成加强版的trigger,FGA介绍详见:)使⽤触发器注意事项1.触发器不接受参数,⼀个表最多可有12个触发器(触发器类型刚好是12种),并且同⼀时间,同⼀事件,同⼀类型的触发器只能有⼀个(保证触发器操作不冲突嘛).2.触发器最⼤为32KB,由于⼤⼩受到限制⾃然也不能使⽤long,blob这样的⼤变量.如果实在是有复杂的逻辑,要弄个很复杂的触发器,可以通过procedure或function实现⼀部分功能,然后调⽤3.因为触发器实际上可以看作触发语句的⼀部分.所以得遵循⼀些约束条件,⽐如不能有事务控制语句 (commit,rollback,savepoint),DDL语句.为啥⼦呢,这些特殊语句与⼀般sql语句的最主要区别是涉及到commit的问题.所以如果触发语句只是⼀般语句的话⾃然不能因为trigger的操作带有commit这样的特性了.创建触发器针对表或视图的触发器格式如下:CREATE [OR REPLACE] TRIGGER trigger_name{BEFORE | AFTER }{INSERT | DELETE | UPDATE [OF column [, column …]]}[OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...]ON [schema.]table_name | [schema.]view_name[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}][FOR EACH ROW ][WHEN condition]PL/SQL_BLOCK | CALL procedure_name;先来看⼀个简单的,statement级别的trigger怎么创建.假如有表tb1,每insert⼀点就通过trigger在tblog中记录⼀些信息.create or replace trigger tb1_triggerafter insert on tb1referencing new as new old as olddeclarev_info varchar2(100);beginv_info := "do a insert";insert into tblog(info) values(v_info);end;trigger的创建中有个不太容易理解的内容:⼀针对row级别的trigger旧值新值问题row级别trigger旧值新值针对⼀个表或视图创建trigger时分为statement级别与row级别的trigger.所谓statement级别是说⼀个sql语句触发⼀次trigger,⽽如果是row级别则⼀个sql语句涉及到多⾏数据则trigger会被触发多次.⽽旧值就是指要更改的那⼀⾏数据在被改之前的值,新值就是⽤户更新后值.假如表tt只有⼀列⼀⾏数据:88.然后⽤户执⾏语句update tt set id = 99 where id = 88;则旧值指88,新值指99.那你们可能会问⽤什么⽅式去得到旧值或新值啊.来举例看下假如有表tb(eno int); 和表tblog( info varchar2(100)); 假如在tb上创建trigger,tb每update⼀次则在tblog中记录旧值就更改后的新值.CREATE OR REPLACE TRIGGER tb_triggerBEFORE UPDATEON tbREFERENCING NEW AS new_val OLD AS old_val --在这⾥设置名字,然后可引⽤新值,旧值.如果不指定默认值为new ,old.可以通过:new或:old去引⽤FOR EACH ROWDECLAREv_info varchar2(100);BEGINv_info := 'old value:' ||to_char( :old_val.eno) || 'new value:' || to_char(:new_val.eno);insert into tblog values(v_info);END;条件判断假如只有在涉及到某⼀⾏的操作时触发trigger,假如该触发器是针对updat,delete,insert都触发的情形.咋整呢,⾃然是多⽤些when去判断啊.例如CREATE OR REPLACE TRIGGER tb_triggerBEFORE UPDATE or insert or deleteON tbREFERENCING NEW AS new_val OLD AS old_val --在这⾥设置名字,然后可引⽤新值,旧值FOR EACH ROWwhen (old_val.eno = 99)DECLAREv_info varchar2(100);BEGINcasewhen updating thenv_info := 'old value:' ||to_char( :old_val.eno) || 'new value:' || to_char(:new_val.eno);insert into tblog values(v_info);when inserting thennull;when deleting thennull;end case;END;。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
insert into audit_creation values(audit_seq.nextval,ora_dict_obj_owner,ora_dict_obj_name,sysdate);
end audit_creation;
/
数据操作语言触发器
create [or replace] trigger trigger_name
6.连接
系统或者数据库事件触发器
create [or replace] trigger trigger_name
{before |after} database_event on {database|schema}
[declare]
declaration_statements;
begin
[declaration_statement;]
begin
execution_statements;
end after statement;]
end [trigger_name];
/
instead-of 触发器
create [or replace] trigger trigger_name
数据库定义语言触发器
create [or replace] trigger trigger_name
{before |after| instead of}ddl_event on {database|schema}
[when (logical_expression)]
[declare]
declaration_statements;
end [trigger_name];
/
判断条件 inserting、updating、deleting
在触发器中编写不可更新视图的结构:
1.集合运算符
2.聚集函数
3.case或者decode语句
4.connect by、group by、having或者start with子句
5.distinct运算符
instead of {dml_statement}
on {object_name|database|schema}
for each row
[when (logical_expression)]
[declare]
declaration_statements;
begin
execution_statements;
[pragma autonomous_transaction;]
declaration_statements;
begin
execution_statements;
end [trigger_name];
/
自治事务的理解:
pragma autonomous_transaction;
自治域加在declare块中,有了这样的预处理,就会使定义的对象为一个单独的事务域,与其他事务无关。
begin
execution_statements;
end before each row;]
[after each row is
[declaration_statement;]
begin
execution_statements;
end after each row;]
[after statement is
复合触发器
不支持when子句和pragma
create [or replace] trigger trigger_name
for {insert |update|update of column1[,column2[,column(n+1)]] |delete}
on table_name
,audit_owner_name varchar2(30) not null
,audit_obj_name varchar2(30) not null
,audit_date date not null
)
create or replace trigger audit_creation
before create on schema
compound trigger
[before statement is
[declaration_statement;]
begin
execution_statements;
end before statement;]
[before each row is
[declaration_statement;]
{before |after}
{insert |update|update of column1[,column2[,column(n+1)]] |delete}
on table_name
[for each row]
[when (logical_expression)]
[declare]
execution_statements;
end [trigger_name];
/
例子:
create or replace trigger connection_trigger
after logon on database
begin
user_connection.connecting(sys.login_user);
begin
execution_statements;
end [trigger_name];
/
create sequence audit_seq increment by 1 start with 10000
create table audit_creation
(audit_creation_id numb发器的限制
最大触发器的尺寸 32760 byte
非系统触发器主体不能包含ddl语句、dcl、transaction control language