PLSQL入门与精通(第41章:Before行触发器“:对NEW.列名”进行赋值)

今天周六,早上去了趟花卉市场。
草色侵大路,花枝出苑墙。
草长莺飞二月天,该春游了。

关于表中的DML触发器,到上次为止已经叙述了他们的很基本用法,我们今天介绍一下关于行触发器的另外一个重要的功能:
BEFORE的行触发来更新列值的变更。也就是说,行触发器是在对象行上启动的,但是对于BEFORE的行触发器,
如果我们手工修改“:NEW.列名”的值,会发生什么情况呢?告诉大家我么直接可以修改这个值,也就直接修改了该行的列的值。
(在AFTER的行触发器中进行相同赋值时,会发生编译错误。道理可以想象得到。)
下面介绍一下这个类似的例子:
表中有2列:“登录日”和“最终更新日”,INSERT的时候,“登录日”设置成当前的日期时间(SYSDATE),
UPDATE的时候,“最终更新日”设置为当前的日期时间(SYSDATE)。
这2个值得更新是通过行触发器发生的。
以下是代码的例子:

首先,建立一张表“TEST01”,其中有登录日和最终更新日2列。
SQL> CREATE TABLE TEST01
2 ( A NUMBER,
3 登录日 DATE,
4 最终更新日 DATE)
5 /

为表创建一个触发器:
1 CREATE OR REPLACE TRIGGER TEST01_TRIG
2 /******************************************************************/
3 --设定登录日(INSERT)或最终更新日(UPDAATE)的触发器
4 /*****************************************************************/
5 BEFORE INSERT OR UPDATE
6 ON TEST01
7 FOR EACH ROW --<----指定行触发器
8 BEGIN
9 IF INSERTING THEN --INSERT时
10 :NEW.登录日:=SYSDATE; --给 :NEW.登录日赋值
11 ELSE --UPDATE时
12 :NEW.最终更新日:=SYSDATE; -给 :NEW.最终更新日赋值
13 END IF;
14
END;
SQL> /

触发器已创建。
该触发器启动时点:对TEST01表某一行数据进行INSERT或UPDATE操作之前BEFORE的时候触发的。
第9行:「INSERTING」,判断操作属于INSERT。 类似的也可以通过 “UPDAATING”和“DELETING”判断各自操作类型。
具体逻辑:INSERT的时候给“:NEW.登录日”赋值;其他的时候给“:NEW.最终更新日”赋值。赋的值是SYSDATE。

我们来确认一下执行结果:
首先,INSERT2行数据:
SQL> INSERT INTO TEST01(A) VALUES (1);
创建了一行。
SQL> INSERT INTO TEST01(A) VALUES (2);
创建了一行。

修改系统的DATE类型的日期格式,以便能显示出时分秒。
SQL> ALTER SESSION SET NLS_DATE_FORMAT=‘YY/MM/DD HH24:MI:SS’;
会话已更改。
查询TEST01表:
SQL> SELECT * FROM TEST01;
A 登录日 最终更新日
-------------------------------------------------------
1 21/03/06 14:12:10
2 21/03/06 14:12:19

这样没有使用UPDATE语句,就可以设置登录日了。

那么,接下来针对A=1这一行,进行UPDATE。

SQL> UPDATE TEST01 SET A = 1 WHERE A = 1;
一行已更新。

然后查询一下结果,A=1行的最终更新日被设定了。
SQL> SELECT * FROM TEST01;
A 登录日 最终更新日
-------------------------------------------------------------------
1 21/03/06 14:12:10 21/03/06 14:12:51
2 21/03/06 14:12:19

这样,那个行什么时候被INSERT的,什么时候被UPDAATE的,就自动被记录了。

假如在这里,将登录日列和最终更新日列作为更新对象时会怎么样呢?使我们登录或者更新得值呢,还是触发器里边的值呢?
让我么试一下:
SQL> UPDATE TEST01
2 SET 最终更新日 = TO DATE(“2021/12/31”,“YYYY/MM/DD’)
3 WHERE A = 2;
一行已更新。

SQL> SELECT * FROM TEST01;
A 登录日 最终更新日
--------------------------------------------------------------
1 21/03/06 14:12:10 21/03/06 14:12:51
2 21/03/06 14:12:19 21/03/06 14:13:22 ←这一行的最终更新日不是我们主动跟新的值,而是触发器里边的值

如,对于A=2行,我们目的是想将最终更新日列更新为2021/12/31,但最终更新日是更新时间的SYSDATE值。

结论就是,在BEFORE的行触发器中,如果对“:NEW.列名”进行赋值,即使在该列中指定不同的值进行DML操作,也会强制使用触发器里边的赋给的值。

这就是我们要注意的细节。本次到此为止。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值