Oracle 触发器

一、定义

每当一个特定的数据库操作语句(insert,update,delete)在指定的表上发出时,oracle会自动执行触发器中定义的语句序列

二、创建触发器的语法

CREATE [OR REPLACE] TRIGGER 触发器名
    BEFORE|AFTER
    [DELETE][[or] INSERT] [[or]UPDATE [OF 列名]]
    ON 表名
    [FOR EACH ROW ][WHEN(条件) ]
declare
    ...
begin
    PLSQL 块
End ;

三、触发器类别

触发器分为行级触发器语句级触发器

行级触发器(ROW):sql语句执行后影响了多少行,将会指定对应次数触发器逻辑

语句级触发器(STATEMENT):如果只执行了一次sql语句,那么将只会执行一次触发器逻辑

四、伪记录变量

在触发器中触发语句伪记录变量的值:

触发语句:old:new
Insert所有字段都是空(null)将要插入的数据
Update更新以前该行的值更新后的值
Delete删除以前的值所有字段都是空(null)

伪记录变量只能用于行级触发器

五、案例

5.1 前置触发器

5.1.1 需求

现在修改firstname时,会在lastname后追加'_'

image.png

5.1.2 创建触发器

-- 前置触发器
create or replace trigger my_tri
before 
update of first_name
on HR.EMPLOYEES
for each row 
declare
begin
  -- 通过伪记录变量修改last_name字段的值
  :new.last_name:=:new.last_name || '_';
end;

5.1.3 查看触发器

image.png

5.1.4 测试

执行前:现在要将id为100的员工名字修改为tom

image.png

执行后:lastname自动追加了“

image.png

5.2 后置触发器

注:后置触发器无法修改绑定的数据表值

5.2.1 需求

现在在修改员工名称后,将会自动将修改记录存入日志表中,日志表字段如下:

-- 创建日志表
create table t_name_log(
    update_time date,
    employee_id number,
    old_name varchar2(30),
    new_name varchar2(30)
);

5.2.2 创建触发器

-- 后置触发器
create or replace trigger my_tri_after
after
update of first_name
on HR.EMPLOYEES
for each row 
declare
begin
  -- 向日志表插入记录
  insert into t_name_log values(sysdate,:new.employee_id,:old.first_name,:new.first_name);
end;

5.2.3 测试

执行前:现在要将id为101的员工名称修改为xyy

image.png

执行后:日志表中自动插入相关信息

image.png

### 如何在 Oracle 数据库中创建触发器 #### 创建触发器的语法结构 为了创建一个触发器,在 Oracle 中使用的 SQL 语句遵循如下基本模板: ```sql CREATE OR REPLACE TRIGGER trigger_name {BEFORE | AFTER} {INSERT [OR] UPDATE [OF column_list] [OR] DELETE} ON table_name [FOR EACH ROW] DECLARE -- 声明部分 (可选) BEGIN -- 触发器主体,PL/SQL代码块 END; / ``` 此模板涵盖了触发器的主要构成要素——名称、时间点(`BEFORE` 或 `AFTER`)、事件类型(`INSERT`, `UPDATE`, 或者 `DELETE`),以及作用的目标表名。如果指定了 `[FOR EACH ROW]` 子句,则表示这是一个行级触发器;如果没有指定,则默认为语句级别的触发器[^1]。 #### 实际案例分析 考虑这样一个场景:每当向员工(`employees`)表插入新记录时,希望同步更新部门统计(`department_statistics`)表中的员工数量计数器。为此目的设计了一个名为 `update_dept_stats_on_insert` 的触发器,其具体实现方式如下所示: ```sql CREATE OR REPLACE TRIGGER update_dept_stats_on_insert AFTER INSERT ON employees FOR EACH ROW BEGIN MERGE INTO department_statistics ds USING dual ON (ds.department_id = :new.department_id) WHEN MATCHED THEN UPDATE SET employee_count = employee_count + 1 WHEN NOT MATCHED THEN INSERT (department_id, employee_count) VALUES (:new.department_id, 1); END; / ``` 上述例子展示了如何利用`:new`伪记录访问新增加的数据项,并据此调整其他表格的内容。这里采用的是`MERGE`命令来处理可能存在的两种情况:目标部门已经存在于统计数据表内或是首次录入该部门的信息[^3]。 #### 关键概念解析 - **触发时机** (`BEFORE/AFTER`) - 如果选择 `BEFORE`,则意味着触发动作发生在实际 DML 操作之前,允许修改即将被写入的新值。 - 若选用 `AFTER`,那么相应的逻辑将在完成事务之后被执行,通常用于维护额外的状态或日志记录。 - **触发级别** - 当声明了 `FOR EACH ROW` 后缀时,表明这是个行级触发器,即对于受影响的每一行都会单独调用一次触发程序。 - 缺省情况下不带此关键字,默认构建的就是语句级触发器,仅在整个DML语句结束时激活一次.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值