Oracle 原理:DML触发器和数据库触发器
一、DML触发器
触发器的作用即当某个事件发生时会自动执行执行程序段里的内容。
触发器可以作用于表或者视图,可以指定在insert 或update 或delete 操作前、操作时、操作后 执行特定的程序段。
CREATE [OR REPLACE] TRIGGER triggername BEFORE/INSTEAD OF/AFTER ---选择事件触发(前,时,后)执行 PL/SQL代码块[INSERT [OR] UPDATE [OR] DELETE] ---当执行 插入 、更新、删除前触发ON tblname_or_viewname ---确认作用的表或者视图[Referencing {OLD [AS] old / NEW [AS] new }] [FOR EACH ROW] --指定行级触发器,不指定就是表级触发器[WHEN (condition)] --当符合condition的条件满足时触发
DECLARE-- local variables here
BEGIN;--PL/SQL blockEND triggername ;
在sqlserver 中 Deleted 是一张临时表存即将被更新删除的老信息,对应Oracle 中的 :old ,Inserted 是一张临时表用来存即将插入更新的新信息,对应Oracle 中的 :new。 :new 和:old 表示即将操作的一行数据而不是代表整个数据集,所以,在用这两个的时候通常要加上[FOR EACH ROW] 来指明行触发器。 其中 对于update的操作实际上是先把数据放入:old再删除再把新数据放入:new插入到数据库中。
由于:old是存的是老数据是即将被删除或更改的,所以更新old没意义。after 已经完成的操作后再触发,所以此时对新数据new进行操作是无意义的。当为after时,无法修改 :new的记录。
对于多表视图,是可以改变键保留表中的内容的。也可以对单表视图j进行DML操作
表级触发器在当对表或视图事件触发时,只执行1次。而行级触发器在对表或视图事件触发时,每影响1行数据就会执行1次程序块内容
在DML触发器中 不能使用rollback ,commit 还有DDL语句。
新建练习表 department_tbl:
新建如下触发器,比较效果
create view VW_department_tbl as select * from department_tbl;
--------insert视图VW_department_tbl时,给每行数据Leaders 默认值'BOSS'----
create or replace trigger departInsertDefault2Instead of insert --替换原有的insert语句,且Instead Of 只能作用于视图, WHEN不能用于 INSTEAD OFon VW_department_tblFOR EACH ROW
declare
beginif :new.leaders is null theninsert into department_tbl values(:new.department,:new.all_salary,'BOSS');else insert into department_tbl values(:new.department,:new.all_salary,:new.leaders);end if;
end departInsertDefault2 ;
drop trigger departInsertDefault2;
-----------------------------------
--------insert表department_tbl时,给每行数据Leaders 默认值'BOSS'----
create or replace trigger departInsertDefault1before insert on department_tbl FOR EACH ROWWHEN (new.leaders is null
)declarebegin :new.leaders :='BOSS';
end departInsertDefault1 ;
drop trigger departInsertDefault1;
对触发器2执行
对触发器1执行
新建触发器3,
create or replace procedure dep_insert(dep in department_tbl.department%type ,sal in department_tbl.all_salary%type)
is PRAGMA AUTONOMOUS_TRANSACTION; --自主事物处理
begininsert into department_tbl values(dep,sal,'BOSS');--update department_tbl set leaders='BOSS' where leaders is null and department = dep; --取不到还未提交的数据
commit;
end dep_insert;
/
create or replace trigger departInsertDefault3after insert --after 无法修改基表的数据,需要自主事物处理的存储过程配合,且新数据属于未提交状态on department_tblFOR EACH ROWWHEN (new.leaders is null)declarev_data department_tbl%rowtype;
begin --update department_tbl set leaders='BOSS' where leaders is null and department = :new.department; --无法执行dep_insert( :new.department,:new.all_salary);end departInsertDefault3 ;
drop trigger departInsertDefault3;
执行
总之,如果要修改数据建议用 before ,after适用于数据校验,而Instead of只能作用于视图。
update 示例:
create or replace trigger departInsertDefault4before update on department_tblFOR EACH ROWwhen (old.department = new.department)
declare
begin :new.all_salary := :new.all_salary+:old.all_salary;
end departInsertDefault4 ;
/
--drop trigger departInsertDefault4;truncate table department_tbl;
insert into department_tbl(department,all_salary) values('部门1',2000);
insert into department_tbl(department,all_salary,leaders) values('部门1',2000,'BOSS');
insert into department_tbl(department,all_salary,leaders) values('部门2',3000,'雇佣者1');
update department_tbl set department = '部门999' where Leaders is not null;
update department_tbl set Leaders = 'boss' where Leaders is not null;
commit;
select * from department_tbl;
最后执行结果:
二、模式(DDL)触发器
Create table obj_tbl(
obj_name varchar2(30),
obj_type varchar2(20),
obj_date Date
)create or replace trigger obj_trigger after Create --alter drop
on SCHEMA
BEGINinsert into obj_tbl values( ora_dict_obj_name,ora_dict_obj_type,SYSDATE);
END;
/
ora_client_ip_address | 用于返回客户端的IP地址 |
ora_database_name | 用于返回当前数据库名 |
ora_des_encrypted_password | 用于返回DES加密后的用户口令 |
ora_dict_obj_name | 用于返回DDL操作所对应的数据库对象名 |
ora_dict_obj_name_list(name_list_ OUT ora_name_list_t) | 用于返回字事件中被修改的对象名列表 |
ora_dict_obj_owner | 用于返回DDL操作所对应的对象的所有者名。 |
ora_dict_obj_ower_list(ower_list OUT ora_name_list_t) | 用于返回在事件中被修改对象的所有者列表 |
ora_dict_obj_type | 用于返回DDL操作所对应的数据库对象的类型。 |
ora_grantee(user_list OUT ora_name_list_t) | 用于返回授权时事件授权者。 |
ora_instance_num | 用于返回历程号。 |
ora_is_alter_column(column_name IN VARCHAR2) | 用于检测特定列是否被修改 |
ora_is_creating_nested_table | 用于检测是否正在建立嵌套表 |
ora_is_drop_column(column_name IN VARCHAR2) | 用于检测特定列是否被删除 |
ora_is_servererror(error_number) | 用于检测是否返回了特定Oracle错误。 |
ora_login_user | 用于返回登录用户名 |
ora_sysevent | 用于返回触发 触发器的系统时间名。 |
三、数据库级触发器
----数据库启动触发器-----
create or replace trigger db_trigger
after startup on database
begin insert into obj_tbl values( ora_sysevent,null,SYSDATE);
end;
/
----数据库用户登录触发器-----
create or replace trigger user_trigger
after logon on database
begin insert into obj_tbl values( ora_login_user,ora_client_ip_address,SYSDATE);
end;
/
四、对触发器的操作
alter tigger tiggername ENABLE/DISABLE 打开关闭触发器
select * from dba_triggers/user_triggers 查询触发器信息
Oracle 原理:DML触发器和数据库触发器相关推荐
- mysql数据库的触发器_Mysql数据库触发器
我还是msyql数据库触发器的新手.我想问一下我的台词: CREATE TRIGGER secure_dml3 BEFORE DELETE ON t_pembelian BEGIN IF (SELEC ...
- c语言 mysql触发器_数据库触发器 @符号
8. 函数 内置函数 聚合函数 对一组值进行运算,但返回一个汇总值. AVG 返回组中各值的平均值. 其中忽略 Null 值. CHECKSUM_AGG 返回组中各值的校验和. 将忽略 Null 值. ...
- 销售系统数据库触发器MySQL_mysql数据库触发器详解
2.1 Mysql触发器的基本使用 创建触发器.创建触发器语法如下: CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_n ...
- 什么是数据库触发器?
目录 什么是数据库触发器? 事件 AFTER触发器 INSTEAD OF触发器 特殊数据库对象 定义 用于触发器 复杂的审计 执行业务规则 派生列值 触发器很棘手! 什么是数据库触发器? 数据库触发器 ...
- oracle创建dml触发器,Oracle数据库创建DML触发器
触发器的基本分类 1.行触发器:数据库表中的每一行有变化都会触发一次触发器代码 2.语句触发器:与语句所影响的行数无关,仅触发一次 3.BEFORE触发器:在DML语句执行之前触发 4.ALFTER触 ...
- oracle 数据库 触发器 trigger 语法
http://shixm.iteye.com/blog/401564 关键字: oracle 数据库 触发器 trigger 语法 语法规则: Create [or replace] trigger ...
- ORACLE数据库触发器
ORACLE 触发器其实是PL/SQL块,它类似于存储过程和函数,不过有一点不同的是,触发器是隐式调用的,并不能接收参数. ORACLE触发器有三种类型,分别是:DML触发器, 替代触发器和系统 ...
- Oracle数据库——触发器的创建与应用
一.涉及内容 1.理解触发器的概念.作用和类型. 2.练习触发器的创建和使用. 二.具体操作 (实验) 1.利用触发器对在scott.emp表上执行的DML操作进行安全性检查,只有scott用户登录数 ...
- oracle数据库触发器是否生效,Oracle数据库触发器
第一次写触发器,浪费了一个小时,少了一个;编译不通过 当A表有更新或插入数据时,则触发器执行向B表插入对应条件的数据 1 CREATE OR REPLACE TRIGGER Test -- 触发器名称 ...
最新文章
- Linux挂载Windows共享目录
- MapxTreme2008的打包过程
- OAG – WhoIsWho 同名消歧竞赛发布 | 10万元奖金双赛道
- 梯度提升树(GBDT)原理小结
- 【redis】批量删除key
- 分布式模式之Broker模式
- 字符设备驱动基础篇2——用开发板来调试驱动模块的步骤
- 嵌入式视频处理基础(一)
- android引入开源项目方法,和解决android-support-v4.jar冲突问题
- js代码格式化工具(格式化、压缩、加密压缩)
- mysql中的关键字大全详解_mysql关键字大全
- [技术解读]英伟达NVIDIA的3D-VISION和AMD-HD3D主动快门立体方案
- 再谈Spring(一):Bean的作用域
- 2022年湖北省文化产业示范园(基地)发展专项资金申报条件以及奖励补贴情况!
- CISP含金量如何?
- IEEE软件工程标准词汇表定义需求
- SylixOS x86 HPET 定时器驱动
- 【优化求解】基于蝗虫算法求解单目标问题附matlab代码
- linux开启审计进程,系统运维|Auditd-Linux 服务器安全审计工具
- 经常说的 CPU 上下文切换是什么意思?(下)
热门文章
- Cisco PT模拟实验(16) 路由器重分发配置
- linux下find查找带有指定权限的文件(windows下编译的源代码文件)
- 仿windows关机对话框的提示框效果
- ROC曲线 vs Precision-Recall曲线
- 724 Find Pivot Index
- kafka-eagle报错解决:Kafka version is “-“ or JMX Port is “-1“ maybe kafka broker jmxport disable.
- 【收藏】使用springboot构建rest api远程提交spark任务
- scala Akka并发编程介绍
- centos7 yum安装docker
- Linux uptime指令