Oracle
创建 DML 触发器
需要 CREATE TRIGGER 系统权限。
创建 DML 触发器的语法如下:
CREATE [OR REPLACE] TRIGGER 触发器名
{BEFORE|AFTER|INSTEAD OF} 触发事件 1 [OR 触发事件 2…]
ON 表名
WHEN 触发条件
[FOR EACH ROW]
DECLARE 声明部分
BEGIN
主体部分
END;
其中:
OR REPLACE:表示如果存在同名触发器,则覆盖原有同名触发器。
BEFORE、AFTER 和 INSTEAD OF:说明触发器的类型。 WHEN 触发条件:表示当该条件满足时,触发器才能执行。 触发事件:指 INSERT、DELETE 或 UPDATE 事件,事件可以并行出现,中间用 OR 连接。
对于 UPDATE 事件,还可以用以下形式表示对某些列的修改会引起触发器的动作:
UPDATE OF 列名 1,列名 2…
ON 表名:表示为哪一个表创建触发器。
FOR EACH ROW:表示触发器为行级触发器,省略则为语句级触发器。 触发器的创建者或具有 DROP ANY TIRGGER 系统权限的人才能删除触发器。删除触发器的语法如下:
DROP TIRGGER 触发器名
可以通过命令设置触发器的可用状态,使其暂时关闭或重新打开,即当触发器暂时不
用时,可以将其置成无效状态,在使用时重新打开。该命令语法如下:
ALTER TRIGGER 触发器名 {DISABLE|ENABLE}
其中,DISABLE 表示使触发器失效,ENABLE 表示使触发器生效。 同存储过程类似,触发器可以用 SHOW ERRORS 检查编译错误。
例:
将插入的雇员的名字变成以大写字母开头。
步骤 1:创建和编译以下触发器:
CREATE OR REPLACE TRIGGER INITCAP
BEFORE INSERT
ON EMP
FOR EACH ROW
BEGIN
:new.ename:=INITCAP(:new.ename); END;
执行结果: 触发器已创建。
步骤 2:验证运行结果:
INSERT INTO emp(empno,ename,job,sal) VALUES(1000,'BILL','CLERK',1500);
执行结果: 已创建 1 行。
执行查询:
SELECT ename,job,sal FROM emp WHERE empno=1000;
执行结果:
ENAME JOB SAL
————- ————- ————————
Bill CLERK 1500
说明:在本例中,通过直接为:new.ename 进行赋值,修改了插入的值,但是这种用法只能在 BEFORE 型触发器中使用。验证结果为,在插入语句中雇员名称为大写的 BILL,查询结果中雇员名称已经转换成以大写开头的 Bill。
Mysql
创建Mysql触发器:
语法:
CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name
FOR EACH ROW
BEGIN
trigger_stmt
END;
``
说明:
CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW BEGIN trigger_stmt END;大写的为关键字
trigger_name:Mysql触发器的名字,我常用的命名规则t_name_tableName_(b|a)(i|u|d),t:触发器标识,name:英文名,tableName:表名,
b(BEFORE):标识是触发事件之前,
a(AFTER):标识触发事件之后,
i(insert): 标识insert事件,
u(update):标识update事件,
d(delete):标识delete事件;
trigger_time:触发时间(BEFORE或AFTER)
trigger_event:事件名(insert或update或delete)
tbl_name:表名(必须是永久性表)
trigger_stmt:执行语句(可以是复合语名),使用别名OLD和NEW,能够引用与触发程序相关的表中的列。
例子:
限定一次对雇员的工资修改不超过原工资的10 %。并设计修改案例测试修改成功和修改失败两种情况,给出输出结果。
delimiter $$
drop trigger if exists change_sal$$
create trigger change_sal
before update on emp
for each row
begin
declare error varchar(20);
if new.sal > old.sal*1.10
then set error = '非法修改';
signal sqlstate 'HY000' set Message_TEXT = error;
end if;
end $$
update emp
set sal = 3000
where empno =1000;
update emp
set sal = 4000
where empno =1000;