近日需要用到Oracle触发器,从网上看了些资料,做下摘记。
理论知识
触发器的概念和类型
触发器是一种特殊的存储过程,它在插入,删除或修改特定表中的数据时触发执行,它比数据库本身标准的功能有更精细和更复杂的数据控制能力。数据库触发器有以下的作用:
- 安全性。可以基于数据库的值使用户具有操作数据库的某种权利。
# 可以基于时间限制用户的操作,例如不允许下班后和节假日修改数据库数据。
# 可以基于数据库中的数据限制用户的操作,例如不允许股票的价格的升幅一次超过10%。
# 审计用户操作数据库的语句。
# 把用户对数据库的更新写入审计表。
# 实现非标准的数据完整性检查和约束。触发器可产生比规则更为复杂的限制。与规则不同,触发器可以引用列或数据库对象。例如,触发器可回退任何企图吃进超过自己保证金的期货。
# 提供可变的缺省值。
- 实现复杂的非标准的数据库相关完整性规则。触发器可以对数据库中相关的表进行连环更新。例如,在auths表author_code列上的删除触发器可导致相应删除在其它表中的与之匹配的行。
# 在修改或删除时级联修改或删除其它表中的与之匹配的行。
# 在修改或删除时把其它表中的与之匹配的行设成NULL值。
# 在修改或删除时把其它表中的与之匹配的行级联设成缺省值。
# 触发器能够拒绝或回退那些破坏相关完整性的变化,取消试图进行数据更新的事务。当插入一个与其主健不匹配的外部键时,这种触发器会起作用。例如,可以在books.author_code列上生成一个插入触发器,如果新值与auths.author_code列中的某值不匹配时,插入被回退。
* 自动计算数据值,如果数据的值达到了一定的要求,则进行特定的处理。例如,如果公司的帐号上的资金低于5万元则立即给财务人员发送警告数据。
示例代码
【案例一】
--触发器:
--添加员工信息,流水号作为自动编号(通过序列生成),
--并且判断如果工资小于0,则改为0;如果大于10000,则改为10000。
CREATE TABLE emp2(
e_id NUMBER,
e_no NUMBER,
e_name VARCHAR2(20),
e_sal NUMBER
)
SELECT * FROM emp2;
CREATE SEQUENCE seq_trg_id;
INSERT INTO emp2(e_id,e_no,e_name,e_sal) VALUES(seq_trg_id.nextval,7788,'章子',
1000000000000)
INSERT INTO emp2(e_id,e_no,e_name,e_sal) VALUES(seq_trg_id.nextval,7788,'章子怡',-10)
CREATE OR REPLACE TRIGGER trg_add_emp_info
BEFORE INSERT
ON emp2
FOR EACH ROW
DECLARE
-- local variables here
BEGIN
SELECT seq_trg_id.NEXTVAL INTO :NEW.e_id FROM dual;
IF :NEW.e_sal < 0 THEN
:NEW.e_sal := 0;
ELSIF :NEW.e_sal > 10000 THEN
:NEW.e_sal := 10000;
END IF;
END;
【案例二】
--扩充练习:
--为emp建立触发器,将删除的记录放到emp3表中(autoid,deptno,empno,ename,del_rq-删除日期)
--测试代码
CREATE TABLE emp3(
autoid NUMBER PRIMARY KEY,
deptno NUMBER,
empno NUMBER,
ename VARCHAR2(20),
del_rq DATE
)
CREATE SEQUENCE seq_trg_del_autoid;
INSERT INTO emp
(empno, ename, deptno)
VALUES
(114, '阿娇', 10);
COMMIT;
SELECT * FROM emp;
DELETE emp WHERE empno = 114;
SELECT * FROM emp3;
--答案:
CREATE OR REPLACE TRIGGER trg_del_emp_info
BEFORE DELETE
ON emp
FOR EACH ROW
DECLARE
-- local variables here
BEGIN
INSERT INTO emp3(autoid,deptno,empno,ename,del_rq)
VALUES(seq_trg_del_autoid.NEXTVAL,:OLD.deptno,:OLD.empno,:OLD.ename,sysdate);
END;
Links
问题
我要对表T的删除数据做备份,于是复制一张T_BAK和表T一样的表另加上操作时间字段。建立表T的删除触发器。其实就是在触发器中把删除的记录插入到T_BAK中。但是如果T_BAK的字段非常多,而且写类似的触发器也很多,要是一个一个字段敲,那不是即费事又容易出错。于是想有没有办法可以一次获取:NEW或:OLD的变量的所有列的值呢?查找了半天也没有答案,看似ORACLE没有实现这个功能?
代码类似这样:
create or replace trigger Trig_on_test
before delete on test
referencing old as o --为了练习声明别名
for each row
declare
PK_conflict Exception; --自定义异常,用于练习
iCount int:=0;
begin
select count(*) into iCount from test1 where id=:o.id;
if iCount>0 then
raise PK_conflict;
end if;
--触发器中不能操作触发自己的表
--insert into test1(id,name,op_time) select t.*, sysdate from test t where t.id=:o.id;
insert into test1 values(:o.id,:o.name,sysdate);
--如果TEST1表中字段N多,难道就只能一个个写?考虑过动态SQL,但前题是要取到:Old变量的所有值,如何取?是否支持?
Exception
when PK_conflict then
DBMS_output.put_line('表中已经有这条记录了');
end;
http://stackoverflow.com/questions/786733/oracle-pl-sql-loop-over-trigger-columns-dynamically老外也有这样的疑问
分享到:
相关推荐
调试oracle触发器文档,自己整理的,不懂的可以聊系我
个人亲测oracle触发器调用java程序
1、行级触发器不支持 update 、select 、delete 对自身表的操作。 2、表级触发器 不支持 :new 和 :old对象 所以想要触发器对自身表数据做修该,则用行级触发器得到 :new 和 :old对象中的相关数据,然后将这样的数据...
oracle insert数据成功之后调用触发器,触发器调用存储过程,存储实时调用java http
oracle触发器语法要点
ORACLE触发器、内置程序包教学.doc )
Oracle 触发器 备份 表数据
oracle触发器功能介绍内附具体说明和简单介绍
oracle 触发器 调用 存储过程 Oracle自治事务(Autonomous Transaction)
oracle触发器与存储过程高级编程
Oracle触发器与存储过程高级编程Oracle触发器与存储过程高级编程
触发器是一种特殊的存储过程,它在插入,删除或修改特定表中的数据时触发执行,它比数据库本身标准的功能有更精细和更复杂的数据控制能力。数据库触发器有以下的作用:
Oracle触发器与存储过程高级编程 中文 PDF
oracle触发器 练习,语句,应用,用法
Oracle触发器的概念和类型
oracle触发器执行顺序.pdf
介绍数据库触发器的PPT。内容包括:存储过程的创建与使用;存储过程的查看、编辑和删除;触发器的创建与使用;触发器的查看、编辑、重命名和删除
Oracle触发器与pl/sql存储过程编程 chm格式的
《Oracle触发器与存储过程高级编程》电子版,由于单个压缩文件超过20M,所以压缩成了两个包,这是第二个包。