触发器
触发器的一般语法结构:
create [or replace] trigger Ttrigger_name
{before|after} Triggering_event on table_name
[for each row]
[follows another_trigger]
[enable/disable]
[when condition]
declare
declaration statemebts
begin
executable statements
exception
exception-handling sttements
end;
解析:
create [or replace] trigger: 表示将创建或者替换一个触发器,如果没有写or replace则只会创建一个触发器,当数据库中已经有该触发器了,则新创建不会成功。
Ttrigger_name:触发器的名字
{before|after} Triggering_event on table_name:表示在table_name表上创建的触发器事件发生的前或者后,触发器会触发
Triggering_event:比如插入或者更新等操作,也可能是时间
[for each row]:表示行级触发器,是对每一行数据都会触发判断。若没有这一句,则是语句级触发器,一次触发只会执行一次
[enable/disable]:是触发器启用或禁用选项,默认是启用的,禁用触发器的例句:after trigger trigger_anme disable
follows :可以指定触发器的顺序
declare:后面是申明部分
beigin...end:中间是主体语句
exception后面抛出异常
a、删除一个表,表上的触发器也会一起被删除
触发器的一些作用:
a、执行不能通过使用完整性约束来定义的复杂业务规则
b、维护复杂的安全规则
c、自动生成衍生列的值
d、收集有关访问数据库表的统计信息
e、防止无效的事务
f、提供值审计
触发器不会执行事务控制语句,比如commit和rollback等,当触发器执行时,执行commit和rollback时,触发器也会被提交或者回滚
例句:
1:
CREATE OR REPLACE TRIGGER forbid_emp_trigger
BEFORE INSERT OR DELETE OR UPDATE ON emp
DECLARE
v_currentweak VARCHAR(20);
v_currenthour VARCHAR(20);
BEGIN
SELECT TO_CHAR(SYSDATE,'day'),TO_CHAR(SYSDATE,'hh24')
INTO v_currentweak, v_currenthour FROM dual ;
IF TRIM(v_currentweak)='星期一' OR TRIM(v_currentweak)='星期六'
OR TRIM(v_currentweak)='星期日' THEN
RAISE_APPLICATION_ERROR(-20008,'在周末及周一不允许更新emp数据表!') ;
ELSIF TRIM(v_currenthour)<'9' OR TRIM(v_currenthour)>'18' THEN
RAISE_APPLICATION_ERROR(-20009,'在下班时间不能够修改emp表数据!') ;
END IF;
END;
会判断当前日期,如果在周一、周末或者下班时间,不允许插入,删除,更新数据库数据
2:
create or replace trigger tri_no_gzjiang
before update
on emp
declare
var_data varchar2(20);
begin
select to_char(sysdate,'hh24') into var_date from dual;
if var_date > '12' then
raise_application_error(-20009,'12点之后不能够修改emp表数据!');
end if;
end;
3:
create or replace trigger CASCADE_DEL_UPD
before update of deptno or delete
on dept
for each row
declare
begin
if deleting then
delete from emp where deptno=:old.deptno;
end if;
if updating then
update emp set deptno=:new.deptno
where deptno=:old.deptno;
end if;
end;
4:
--创建一个视图
create or replace view view_emp_dept as
select empno,ename,dept.deptno,dname,job,hiredate
from emp ,dept
where emp.deptno = dept.deptno;
--插入记录
insert into view_emp_dept(empno,ename,deptno,dname,job,hiredate)
values (999,'ttgg',10,'ACCOUNTING','CASHIER',sysdate);
--插入数据失败,通过关联触发器来
--创建触发器
create or replace trigger tri_insert_view
instead of insert
on view_emp_dept
for each row
declare
row_dept dept%rowtype;
begin
select * into row_dept from dept where deptno=:new.deptno;
if sql%notfound then
insert into dept(deptno,dname) values(:new.deptno,:new.dname);
end if;
insert into emp(empno,ename,deptno,job,hiredate)
values (:new.empno,:new.ename,:new.deptno,:new.job,:new.hiredate);
end;
--验证触发器
insert into view_emp_dept(empno,ename,deptno,dname,job,hiredate)
values (999,'ttgg',10,'ACCOUNTING','CASHIER',sysdate);
select * from view_emp_dept;
尽管很渺小,但终究会变得伟大
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?