Oracle创建触发器实例

一 创建DML 触发器
DML触发器基本要点:
触发时机:指定触发器的触发时间。如果指定为BEFORE,则表示在执行DML操作之前触发,以便防止某些错误操作发生或实现某些业务规则;如果指定为AFTER,则表示在执行DML操作之后触发,以便记录该操作或做某些事后处理。
触发事件:引起触发器被触发的事件,即DML操作(INSERT、UPDATE、DELETE)。既可以是单个触发事件,也可以是多个触发事件的组合(只能使用OR逻辑组合,不能使用AND逻辑组合)。
条件谓词:当在触发器中包含多个触发事件(INSERT、UPDATE、DELETE)的组合时,为了分别针对不同的事件进行不同的处理,需要使用Oracle提供的如下条件谓词。
(1)INSERTING:当触发事件是INSERT时,取值为TRUE,否则为FALSE。
(2)UPDATING [(column_1,column_2,…,column_x)]:当触发事件是UPDATE 时,如果修改了column_x列,则取值为TRUE,否则为FALSE。其中column_x是可选的。
(3)DELETING:当触发事件是DELETE时,则取值为TRUE,否则为FALSE。
解发对象:指定触发器是创建在哪个表、视图上。
触发类型:是语句级还是行级触发器。
触发条件:由WHEN子句指定一个逻辑表达式,只允许在行级触发器上指定触发条件,指定UPDATING后面的列的列表。
当触发器被触发时,要使用被插入、更新或删除的记录中的列值,有时要使用操作前、 后列的值。可以使用:NEW和 :OLD 。
:NEW 修饰符表示操作完成后列的值
:OLD 修饰符表示操作完成前列的值
:NEW和:OLD的具体使用见表9-1。
表9-1 :NEW和:OLD的值
特性 INSERT UPDATE DELETE
OLD NULL 实际值 实际值
NEW 实际值 实际值 NULL

【例9-1】建立职工表emp的日志表EMPPLOYEES_LOG。当职工表进行DML操作时候,把职工表具体的操作名称,时间等信息插入到日志表中。
具体代码如下:
–第九章\sfq.sql

–建立职工表
create table emp
(empno NUMBER(4), --职工号
job VARCHAR2(10), --岗位
sal NUMBER(7,2) --薪水
);
–往职工表中插入数据
insert into EMP
select ‘1105’,‘工程师’,6500 from dual;

Insert into EMP
select ‘1135’,‘质检员’,3000 from dual;

Commit;

–建立日志表

create table EMPLOYEES_LOG
(
WHO VARCHAR2(30),
WHEN DATE,
ACTION VARCHAR2(50),
TALENME VARCHAR2(30)
)
CREATE OR REPLACE Trigger biud_employee_copy
Before insert or update or delete
On emp
Declare
tn VARCHAR2(10);
Begin
tn:=‘员工表’;
– :GLOBAL.USERNAME:=‘hzm’
if inserting then
Insert into employees_log(
Who,when,TALENME,action)
Values(user, sysdate,tn,‘插入新数据’);
END IF;
if updating then
Insert into employees_log(
Who,when,TALENME,action)
Values( user, sysdate,tn,‘更新数据’);
END IF;
if deleting then
Insert into employees_log(
Who,when,TALENME,action)
Values( user, sysdate,tn,‘删除数据’);
END IF;
End;

–插入数据
insert into EMP
select ‘1237’,‘项目经理’,8000 from dual;

–删除数据
Delete from EMP where empno=‘1135’;
Commit;

Select * from emp;

Select * from EMPLOYEES_LOG;

查询emp 表数据,结果如图9-1所示。

图9-1查询职工表的数据。

查询日志表数据,结果如图9-2所示。

图9-2查询日志表的数据。

【例9-2】建立职工表emp和审查表audit_emp_values,在职工表上建立一个触发器,当该表进行DML 操作时候,记录表中的旧值和新值,然后插入审查表。
具体代码如下:
– 第九章\sfq.sql

–建立职工表
create table emp
(empno NUMBER(4),
job VARCHAR2(10),
sal NUMBER(7,2)
)
–建立审查表
CREATE TABLE audit_emp_values
(user_name VARCHAR2(50),
timestamp DATE,
id NUMBER(4),
old_last_name VARCHAR2(10),
new_last_name VARCHAR2(10),
old_title VARCHAR2(10),
new_title VARCHAR2(10),
old_salary NUMBER(7,2),
new_salary NUMBER(7,2));

–建立行级触发器
CREATE OR REPLACE TRIGGER audit_emp_values
AFTER
DELETE OR INSERT OR UPDATE ON emp
FOR EACH ROW
BEGIN
INSERT INTO audit_emp_values (user_name,
timestamp, id,
old_title, new_title, old_salary, new_salary)
VALUES (USER, SYSDATE, :old.empno,
:old.job, :new.job, :old.sal, :new.sal);
END;

----职工表执行dml 操作
insert into emp (empno,job,sal) values(9,‘worker’,3000);
insert into emp (empno,job,sal) values(8,‘hunter’,100);
Commit;
Update emp set sal=4500 where empno=‘8’ ;
Commit;
delete from emp where job=‘hunter’;

Select * from emp;

Select * from audit_emp_values;

查询职工表,结果如图9-3所示。

图9-3执行DML操作后查询职工表的数据。

查询审查表,结果如图9-4所示。

图9-4执行DML操作后查询职工表的数据
三创建INSTEAD OF 触发器
具体格式如下:
CREATE [OR REPLACE] TRIGGER trigger_name
INSTEAD OF
{INSERT | DELETE | UPDATE [OF column [, column …]]}
[OR {INSERT | DELETE | UPDATE [OF column [, column …]]}…]
ON [schema.] view_name --只能定义在视图上
[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]
[FOR EACH ROW ] --因为INSTEAD OF触发器只能在行级上触发,所以没有必要指定
[WHEN condition]
PL/SQL_block | CALL procedure_name;

INSTEAD OF 选项使Oracle激活触发器,而不执行触发事件。只能对视图和对象视图建立INSTEAD OF触发器,而不能对表、模式和数据库建立INSTEAD OF 触发器。
【例9-3】建立视图emp_view,取表emp记录数和总工资数。建立INSTEAD OF
触发器,当删除表的数据后,可以删除视图的的数据,最后查询删除数据后视图的数据。
建立触发器,代码如下:
– 第九章\sfq.sql

–建 emp表,插入记录

create table emp
(empno NUMBER(4),
job VARCHAR2(10),
sal NUMBER(7,2)
);
insert into emp (empno,job,sal) values(9,‘worker’,3000);
Commit;

–建立视图,统计职工表的总职工数和总工资
CREATE OR REPLACE VIEW emp_view AS
SELECT empno, count(*) total_employeer, sum(sal) total_salary
FROM emp GROUP BY empno;

–建立触发器,当删除职工表数据时候触发
CREATE OR REPLACE TRIGGER emp_view_delete
INSTEAD OF DELETE ON emp_view FOR EACH ROW
BEGIN
DELETE FROM emp WHERE empno= :old.empno;
END emp_view_delete;

–删除视图数据
DELETE FROM emp_view WHERE empno=9;
Commit;
–查询视图的数据
Select * from emp_view

查询视图,结果如图9-5所示

图9-5查询视图emp_view的数据
四 创建系统事件触发器
Oracle 10G提供的系统事件触发器可以在DDL或数据库系统上被触发。DDL指的是数据定义语言,如CREATE 、ALTER及DROP 等。而数据库系统事件包括数据库服务器的启动或关闭、用户的登录与退出、数据库服务错误等。创建系统触发器的语法如下:
CREATE OR REPLACE TRIGGER [sachema.]trigger_name
{BEFORE|AFTER}
{ddl_event_list | database_event_list}
ON { DATABASE | [schema.]SCHEMA }
[WHEN condition]
PL/SQL_block | CALL procedure_name;
dl_event_list:一个或多个DDL 事件,多个事件中间用 OR 分开。
database_event_list:一个或多个数据库事件,多个事件中间间用 OR 分开。
系统事件触发器既可以建立在一个模式上,又可以建立在整个数据库上。当建立在模式(SCHEMA)之上时,只有模式所指定用户的DDL操作和它们所导致的错误才激活触发器, 默认时为当前用户模式。当建立在数据库(DATABASE)之上时,该数据库所有用户的DDL操作和他们所导致的错误,以及数据库的启动和关闭均可激活触发器。要在数据库之上建立触发器时,要求用户具有ADMINISTER DATABASE TRIGGER权限。
系统触发器的种类和事件出现的时机(前或后),见表9-2。
表9-2 系统时间允许的时机
事件 允许的时机 说明
STARTUP AFTER 启动数据库实例之后触发
SHUTDOWN BEFORE 关闭数据库实例之前触发(非正常关闭不触发)
SERVERERROR AFTER 数据库服务器发生错误之后触发
LOGON AFTER 成功登录连接到数据库后触发
LOGOFF BEFORE 开始断开数据库连接之前触发
CREATE BEFORE
AFTER 在执行CREATE语句创建数据库对象之前、之后触发
DROP BEFORE
AFTER 在执行DROP语句删除数据库对象之前、之后触发
ALTER BEFORE
AFTER 在执行ALTER语句更新数据库对象之前、之后触发
DDL BEFORE
AFTER 在执行大多数DDL语句之前、之后触发
GRANT BEFORE
AFTER 执行GRANT语句授予权限之前、之后触发
REVOKE BEFORE
AFTER 执行REVOKE语句收权限之前、之后触犯发
RENAME BEFORE
AFTER 执行RENAME语句更改数据库对象名称之前、之后触犯发
AUDIT / NOAUDIT BEFORE
AFTER 执行AUDIT或NOAUDIT进行审计或停止审计之前、之后触发

【例9-4】建立事件表ddl_event ,当数据库有DML操作,把具体事件名称和时间插入事件表中。
建立事件表,代码如下:
–第九章\sfq.sql

create table ddl_event
(crt_date timestamp PRIMARY KEY,
event_name VARCHAR2(20),
user_name VARCHAR2(10),
obj_type VARCHAR2(20),
obj_name VARCHAR2(20));
建立触发器,当发生ddl操作,把时间名称等插入事件表,代码如下:
CREATE OR REPLACE TRIGGER tr_ddl
AFTER DDL ON SCHEMA
BEGIN
  INSERT INTO ddl_event VALUES
  (systimestamp,ora_sysevent, ora_login_user,
  ora_dict_obj_type, ora_dict_obj_name);
END tr_ddl;

【例9-5】建立登录事件表log_event ,当数据库有登录或退出操作,把具体事件名称和用户等信息插入时间表中。
具体代码如下:
–第九章\sfq.sql

CREATE TABLE log_event
(user_name VARCHAR2(10),
address VARCHAR2(20),
logon_date timestamp,
logoff_date timestamp);

–创建登录触发器
CREATE OR REPLACE TRIGGER tr_logon
AFTER LOGON ON DATABASE
BEGIN
INSERT INTO log_event (user_name, address, logon_date)
VALUES (ora_login_user, ora_client_ip_address, systimestamp);
END tr_logon;
–创建退出触发器
CREATE OR REPLACE TRIGGER tr_logoff
BEFORE LOGOFF ON DATABASE
BEGIN
INSERT INTO log_event (user_name, address, logoff_date)
VALUES (ora_login_user, ora_client_ip_address, systimestamp);
END tr_logoff;
9.5触发器的编译和删除
1)重新编译触发器
如果在触发器内调用其它函数或过程,当这些函数或过程被删除或修改后,触发器的状态将被标识为无效。当DML语句激活一个无效触发器时,Oracle将重新编译触发器代码,如果编译时发现错误,这将导致DML语句执行失败。
在PL/SQL程序中可以调用ALTER TRIGGER语句重新编译已经创建的触发器,格式如下:
ALTER TRIGGER [schema.] trigger_name COMPILE [ DEBUG]
其中:DEBUG 选项要器编译器生成PL/SQL 程序条使其所使用的调试代码。
2) 启用触发器的格式如下:
ALTER TRIGGER trigger_name ENABLE;
3)禁用触发器的格式如下:
alter trigger trigger_name disable;
4)删除触发器格式如下:
  DROP TRIGGER trigger_name;
当删除其他用户模式中的触发器名称,需要具有DROP ANY TRIGGER系统权限,当删除建立在数据库上的触发器时,用户需要具有ADMINISTER DATABASE TRIGGER系统权限。此外,当删除表或视图时,建立在这些对象上的触发器也随之删除。
触发器优点:
强化约束:强制复杂业务的规则和要求,能实现比check语句更为复杂的约束。
跟踪变化:触发器可以侦测数据库内的操作,从而禁止数据库中未经许可的更新和变化。
级联运行:侦测数据库内的操作时,可自动地级联影响整个数据库的各项内容。
嵌套调用:触发器可以调用一个或多个存储过程。触发器最多可以嵌套32层。
缺点:性能较低。因为在运行触发器时,系统处理的大部分时间花费在参照其他表的处理上,这些表既不在内存中也不在数据库设备上,而删除表和插入表总是位于内存中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/76922.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Filename too long 错误

Filename too long 错误表明文件名超出了文件系统或版本控制系统允许的最大长度。 可能的原因 文件系统限制 不同的文件系统对文件名长度有不同的限制。例如,FAT32 文件名最长为 255 个字符,而 NTFS 虽然支持较长的文件名,但在某些情况下也…

网络不可达network unreachable问题解决过程

问题:访问一个环境中的路由器172.16.1.1,发现ssh无法访问,ping发现回网络不可达 C:\Windows\System32>ping 172.16.1.1 正在 Ping 172.16.1.1 具有 32 字节的数据: 来自 172.16.81.1 的回复: 无法访问目标网。 来自 172.16.81.1 的回复:…

Python设计模式:备忘录模式

1. 什么是备忘录模式? 备忘录模式是一种行为设计模式,它允许在不暴露对象内部状态的情况下,保存和恢复对象的状态。备忘录模式的核心思想是将对象的状态保存到一个备忘录对象中,以便在需要时可以恢复到之前的状态。这种模式通常用…

Python基础语法3

目录 1、函数 1.1、语法格式 1.2、函数返回值 1.3、变量作用域 1.4、执行过程 1.5、链式调用 1.6、嵌套调用 1.7、函数递归 1.8、参数默认值 1.9、关键字参数 2、列表 2.1、创建列表 2.2、下标访问 2.3、切片操作 2.4、遍历列表元素 2.5、新增元素 2.6、查找元…

JavaEE学习笔记(第二课)

1、好用的AI代码工具cursor 2、Java框架:Spring(高级框架)、Servelt、Struts、EJB 3、Spring有两层含义: ①Spring Framework(原始框架) ②Spring家族 4、Spring Boot(为了使Spring简化) 5、创建Spring Boot 项目 ① ② ③…

基于Flask与Ngrok实现Pycharm本地项目公网访问:从零部署

目录 概要 1. 环境与前置条件 2. 安装与配置 Flask 2.1 创建虚拟环境 2.2 安装 Flask 3. 安装与配置 Ngrok 3.1 下载 Ngrok 3.2 注册并获取 Authtoken 4. 在 PyCharm 中创建 Flask 项目 5. 运行本地 Flask 服务 6. 启动 Ngrok 隧道并获取公网地址 7. 完整示例代码汇…

Ragflow、Dify、FastGPT、COZE核心差异对比与Ragflow的深度文档理解能力​​和​​全流程优化设计

一、Ragflow、Dify、FastGPT、COZE核心差异对比 以下从核心功能、目标用户、技术特性等维度对比四款工具的核心差异: 核心功能定位 • Ragflow:专注于深度文档理解的RAG引擎,擅长处理复杂格式(PDF、扫描件、表格等)的…

LeetCode[232]用栈实现队列

思路: 一道很简单的题,就是栈是先进后出,队列是先进先出,用两个栈底相互对着,这样一个队列就产生了,右栈为空的情况,左栈栈底就是队首元素,所以我们需要将左栈全部压入右栈&#xff…

postman 删除注销账号

一、删除账号 1.右上角找到 头像,view profile https://123456-6586950.postman.co/settings/me/account 二、找回账号 1.查看日志所在位置 三、postman更新后只剩下history 在 Postman 中,如果你发现更新后只剩下 History(历史记录&…

微服务相比传统服务的优势

这是一道面试题,咱们先来分析这道题考察的是什么。 如果分析面试官主要考察以下几个方面: 技术理解深度 你是否清楚微服务架构(Microservices)和传统单体架构(Monolithic)的本质区别。能否从设计理念、技术…

【KWDB 创作者计划】_深度学习篇---向量指令集

文章目录 前言一、加速原理数据级并行(DLP)计算密度提升减少指令开销内存带宽优化隐藏内存延迟二、关键实现技术1. 手动向量化(Intrinsics)优势挑战2. 编译器自动向量化限制3. BLAS/LAPACK库优化4. 框架级优化三、典型应用场景矩阵运算卷积优化归一化/激活函数嵌入层(Embe…

跳跃游戏(每日一题-中等)

题解:定义一个变量,用来存储可以到达的最远位置。初始化为0。 然后对数组进行遍历,遍历开始的时候,先判断当前这个位置和最远位置谁大,如果最远位置比较大,那么就说明当前这个位置也能达到,就看…

第七篇:linux之基本权限、进程管理、系统服务

第七篇:linux之基本权限、进程管理、系统服务 文章目录 第七篇:linux之基本权限、进程管理、系统服务一、基本权限1、什么是权限?2、为什么要有权限?3、权限与用户之间的关系?4、权限对应的数字含义5、使用chmod设定权…

音视频小白系统入门课-2

本系列笔记为博主学习李超老师课程的课堂笔记,仅供参阅 往期课程笔记传送门: 音视频小白系统入门笔记-0音视频小白系统入门笔记-1 课程实践代码仓库:传送门 音视频编解码 可以通过ffmpeg -f avfoundation -list_devices true -i "&…

外卖“三国杀”开新局,饿了么已手握AI牌

【潮汐商业评论/原创】 01 新战役,新变量 外卖行业,又迎来了新一轮战役。 前有京东宣布斥资百亿进军外卖市场,后有美团宣布发布即时零售品牌“美团闪购”。双方在隔空秀肌肉、彰显自身实力的同时,行业巨头围绕本地生活服务的攻…

HAProxy 和 Keepalived 区别

HAProxy 和 Keepalived 是在构建高可用和可扩展Web服务时常用的两个开源软件,但它们的核心功能和目的有显著区别。 简单来说: HAProxy: 主要是一个 负载均衡器 (Load Balancer) 和 反向代理 (Reverse Proxy)。它负责将客户端的请求智能地分发到后端的多…

YOLO算法的革命性升级:深度解析Repulsion损失函数在目标检测中的创新应用

## 一、目标检测的痛点与YOLO的局限性 在自动驾驶、智能监控等复杂场景中,目标检测算法常面临致命挑战——遮挡问题。当多个物体相互遮挡时,传统检测器容易出现漏检、误检现象,YOLO系列算法尽管在速度与精度上表现优异,但在处理密集遮挡目标时仍存在明显短板。 ### 1.1 遮…

第一篇:Django简介

第一篇:Django简介 文章目录 第一篇:Django简介一、纯手写一个简易版的web框架1、软件开发架构2、HTTP协议3、简易的socket服务端4、wsgiref模块5、动静态网页6、后端获取当前时间展示到html页面上7、字典数据传给html文件8、数据从数据库中获取的展示到…

【笔记】CentOS7部署K8S集群

一、初始化(所有节点机器都要执行) 1. 关闭firewall防火墙 systemctl disable firewalld.service systemctl stop firewalld.service2. 关闭SELinux 临时关闭 setenforce 0永久关闭 vim /etc/selinux/config SELINUXenforcing 改成 SELINUXdisable…

Ethan独立开发产品日报 | 2025-04-22

1. Agent Simulate 用数千个数字人来测试你的人工智能应用。 Agent Simulate 让你在发布之前,能够在一个安全的环境中模拟和测试大型语言模型(LLM)代理。它帮助你调试行为、加快迭代速度,并降低生产风险,专为代理开发…