【oracle】触发器简单实现

摘要:
它的执行由事件自动和隐式触发。[例如,当对表(insert:触发器和存储过程之间的唯一区别是,触发器不能执行execute语句调用,而是在用户执行Transact-SQL语句时自动触发执行。CREATE[OREPLACE]TRIGGERtrigger_name{BEFORE | AFTER}{insert | DELETE | UPDATE[OFcolumn[。

目标:实现实时备份uertest表数据至usertest_temp中,两表结构一致

解决:用oracle触发器实现同步

结果:

1.建表

-- 简单的用户表
create table USERTEST
(
  NAME     VARCHAR2(20) not null,
  AGE      NUMBER,
  ISDELETE VARCHAR2(4)
)
-- 备份表
create table USERTEST_TEMP
(
  NAME     VARCHAR2(20) not null,
  AGE      NUMBER,
  ISDELETE VARCHAR2(4)
)

2、触发器

CREATE OR REPLACE TRIGGER tr_user_temp 
BEFORE 
INSERT OR UPDATE OR DELETE 
ON usertest FOR EACH ROW
declare
BEGIN
IF inserting THEN
	INSERT INTO usertest_temp(name,age,isdelete)
        VALUES
	(
	:new.name,
	:new.age,
	:new.isdelete
	);
ELSIF deleting THEN
	DELETE usertest_temp
        WHERE
        NAME =:OLD.NAME ;
ELSIF updating THEN
	update usertest_temp
        SET age =:new.age,
        isdelete =:new.isdelete
        WHERE
	NAME =:OLD.NAME ;
END IF ;
END ;

3.对USERTEST表执行增删改查操作,则usertest_temp表也会相应更改

注意:标点符号一定要是英文标点,否则会有编译错误

理解
概念:
触发器(trigger)是个特殊的存储过程,它的执行是由事件来触发自动地隐式运行[比如当对一个表进行操作( insert,delete,update)时就会激活它执行]。触发器经常用于加强数据的完整性约束和业务规则等。 触发器可以从 DBA_TRIGGERS ,USER_TRIGGERS 数据字典中查到。触发器与存储过程的唯一区别是触发器不能执行EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发执行。

创建语法:

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;

注释:
CREATE [OR REPLACE] TRIGGER
:创建或替换
BEFORE 和AFTER:触发时序分别为前触发【在执行触发事件之前触发当前所创建的触发器】和后触发方式【在执行触发事件之后触发当前所创建的触发器】
FOR EACH ROW:行触发器。
        行触发器:受到影响的每个数据行,只要它们符合触发约束条件,均激活一次触发器;
        语句触发器:将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。
        当省略FOR EACH ROW 选项时,BEFORE 和AFTER 触发器为语句触发器,而INSTEAD OF 触发器则只能为行触发器。
REFERENCING:说明相关名称,在行触发器的PL/SQL块和WHEN 子句中可以使用相关名称参照当前的新、旧列值,默认的相关名称分别为OLD和NEW。触发器的PL/SQL块中应用相关名称时,必须在它们之前加冒号(:),但在WHEN子句中则不能加冒号。
WHEN 子句说明触发约束条件。
Condition 为一个逻辑表达时,其中必须包含相关名称,而不能包含查询语句,也不能调用PL/SQL 函数。
WHEN 子句指定的触发约束条件只能用在BEFORE 和AFTER 行触发器中,不能用在INSTEAD OF 行触发器和其它类型的触发器中。

注意以下几点:

1.触发器不接受参数。
2.一个表上最多可有12个触发器,但同时、同事、同类的触发器只能有一个且不可矛盾。
3.在一个表上的触发器越多,对在该表上的DML操作的性能影响就越大。
4. 触发器最大为32KB。若确实需要,可以先建立过程,然后在触发器中用CALL语句进行调用。
5. 在触发器的执行部分只能用DML语句(SELECT、INSERT、UPDATE、DELETE),不能使用DDL语句(CREATE、ALTER、DROP)。
6. 触发器中不能包含事务控制语句(COMMIT,ROLLBACK,SAVEPOINT)。
7.在触发器主体中调用的任何过程、函数,都不能使用事务控制语句。
8. 在触发器主体中不能申明任何Long和blob变量。新值new和旧值old也不能向表中的任何long和blob列。
9.不同类型的触发器(如DML触发器、INSTEAD OF触发器、系统触发器)的语法格式和作用有较大区别。

问题:当触发器被触发时,要使用被插入、更新或删除的记录中的列值,有时要使用操作前、 后列的值.
实现:  :NEW 修饰符访问操作完成后列的值
           :OLD 修饰符访问操作完成前列的值

特性INSERTUPDATEDELETE
OLDNULL实际值实际值
NEW  实际值实际值NULL


参考学习:
  http://www.cnblogs.com/huyong/archive/2011/04/27/2030466.html

http://www.jb51.net/article/18252.htm

免责声明:文章转载自《【oracle】触发器简单实现》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Modern UI for WPF 开源项目(2):我的第一个Modern UI App微信小程序 npm 找不到npm包 没有找到可以构建的npm包 如何使用第三方npm组件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mysql数据库乱码恢复

mysql数据库字符集不支持导致数据乱码恢复    mysqldump --default-character-set=latin1 -d test >table.sql # -d只导出数据库表结构,不导表数据mysqldump --default-character-set=latin1 -t test > data.sql# -t 只导出数...

plsql导出导入 表结构、表数据、存储过程等

导出:首先点击   TOOLS,选择  EXPORT TABLES  选中你需要导出的表,   勾选  “Create tables” 是因为在导入的数据库中没有此表 如果勾选"Drop tables" 而没有勾选 “Create tables” ,而数据库中没有此表,会报表和视图不存在 Output file 为导出的路径   如果你想导的表  数据记录...

数据可视化之DAX篇(二十五)PowerBI常用的度量值:累计至今

https://zhuanlan.zhihu.com/p/64999937 经常碰到本年至今、本月至今的数据计算,其实还有一类计算是,从历史最早日期至今的累计计算,比如从开业到现在总共卖出了多少件商品,累计实现了多少销售额等。 本年累计称为YTD,历史至今的累计是不是可以称为HTD呢:) ;这样的时间段很可能是跨年的,所以时间智能函数并不适用,不过不用时间...

数据库定时清理脚本配置

定时 数据库清理的两个脚本: 按天删除: #!/bin/bash ndate=3 datestr=`date -d "-$ndate day" +%Y-%m-%d` #生成ndate天前的日期,如: echo $datestr delSqlStr="DELETE FROM xxxx WHERE GeneDate = '$datestr'" #SQL语句...

showdoc升级问题,showdoc错误日志

showdoc自带错误日志。目录位于网站根目录的server/Application/Runtime/Logs/Api目录下,如果没有任何内容需要添加可写权限。 showdoc升级后,建议把MySQL改成Sqlite,这里我们没改。后期出现了一系列问题,观察这个位置的日志就能解决。 建议升级的用户看一下网站根目录下server/Application/Ho...

mysql binlog抽取某个表的数据

1.先把binlog文件转化为sql sudo mysqlbinlog /var/mysql/var/mysql-bin.000057 --base64-output=decode-rows -v > /var/mydiag.sql 2.抽取某一个表的数据 grep -B0 -A27 -w 'DELETE FROM `kdb`.`t_diag_re...