发布时间:2025-12-09 11:54:59 浏览次数:1
参考:https://blog.csdn.net/weixin_41649106/article/details/86981325
https://blog.csdn.net/htj10/article/details/114629358
触发器的应用场景
准备工作:
create table t_salary(id number(8), sal number(10,2));insert into t_salary(id, sal) values(1, 8000);select * from t_salary;
创建触发器:
/**涨后的薪水不能低于涨前的薪水1 :old 和 :new 代表同一条记录2 :old 代表操作该行之前,这一行的值 :new 代表操作该行之后,这一行的值*/create or replace trigger checkSalary before update on t_salary for each rowdeclare -- local variables here 没有变量声明的话,declare可以省略begin -- if 涨后的薪水 < 涨前的薪水 then 如何表示呢 ? if :new.sal < :old.sal then raise_application_error(-20002,'涨后的薪水:'|| :new.sal ||'小于涨前的薪水:'||:old.sal); end if;end checkSalary;
测试:
SQL> update t_salary set sal=7000 where id=1;update t_salary set sal=7000 where id=1 *第 1 行出现错误:ORA-20002: 涨后的薪水:7000小于涨前的薪水:9000ORA-06512: 在 "SCOTT.CHECKSALARY", line 6ORA-04088: 触发器 'SCOTT.CHECKSALARY' 执行过程中出错
删除触发器
--删除 触发器drop trigger checkSalary;
/*删除前,将数据备份*/create or replace trigger tri_sal_delete_bk before delete on t_salary for each rowbegin insert into t_salary_del(id,sal) values(:old.id, :old.sal); -- commit; -- 注意不可以有提交,会报错ora-04092end tri_sal_delete_bk;
注意:DML(delete/update/insert)触发器中不能使用DDL(CREATE,drop,ALTER)语句,也不能使用事务控制语句(ROLLBACK, COMMIT,SAVEPOINT)。特别注意的是,在触发器的主体中引用的函数(function)/过程(procedure)中也不能有事物控制语句。
/**非工作时间(星期六 星期日, 非9点~18点的区间)禁止写入数据首先要搞清楚: 触发器的类型--语句级触发器。不管插入了多少条数据,没有必要对每一行数据都进行校验,只要不在这个时间段内,都不让插入。*/create or replace trigger tri_addSalaryCheck before insert on t_salarydeclare -- local variables herebegin if to_char(sysdate, 'day') in ('星期六', '星期日') or to_number(to_char(sysdate, 'hh24')) not between 9 and 18 then -- 禁止insert raise_application_error(-20001,'非工作时间禁止插入数据'); end if;end tri_addSalaryCheck;-- 建表:CREATE TABLE t_user(U_ID NUMBER(8), UNAME VARCHAR2(20), UPASSWORD VARCHAR2(20));-- 建立序列:CREATE SEQUENCE SEQ_TUSER INCREMENT BY 1MINVALUE 1 --最小值 MAXVALUE 99999999 --最大值由NUMBER(8) NOCYCLE --不打环 NOCACHE --不缓存 ORDER;COMMIT; -- 然后建立before的触发器:CREATE OR replace TRIGGER TRG_ADDTUSER BEFORE insert ON t_userFOR EACH ROWBEGINSELECT SEQ_TUSER.NEXTVAL INTO :NEW.U_ID FROM DUAL;END TRG_ADDTUSER;-- 测试:insert INTO t_user (UNAME,UPASSWORD) VALUES ('libai','589avf');insert INTO t_user (UNAME,UPASSWORD) VALUES ('zhangsan','ko098');COMMIT;select * from t_user; 常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。