mysql markdown_MySQL 触发器学习-markdown->html 格式测试

触发器(Trigger)

目标

定义

应用场景

创建语法

创建简单触发器

定义

理解: 触发器是一类特定的事务, 可以监视某种数据操作(insert, update, delete) 并触发相关操作(insert, update, delete).

即监察增删改, 触发增删改, sql_01 ...... 触发-->sql_n

应用场景

当向一张表增删记录时, 需要在相关表中进行同步操作.(订单, 销量增加, 库存减少..)

当表上的某列数据值与其他表中的数据有联系时.(信用卡消费,额度校验)

跟踪某张表.(花名册更新)

创建语法4要素

监视地点 table

监视事件 insert, update, delete

触发时间 afer, before

触发事件 insert, update, delete

触发器-案例

需求:

商品表: goods

订单表: ord

当下1个订单时, 对应的商品库存减少

分析:

监视谁: ord

监视动作: insert

触发时间: after

触发事件: update

(当ord插入后, 触发update)

xxxxxxxxxx

-- triger 语法结构

create trigger t1

after

inset

on ord

for each row

begin

update goods .....

end;

x

-- 创建一个数据库 mysql_advance

create database sql_advance charset=utf8;

use sql_advance;

-- 创建表

create table goods(

gid int,

name varchar(20),

num smallint

);

create table ord(

oid int,

gid int,

much smallint

);

-- 插入数据-goods表

insert into goods values

(1, 'cat', 34),

(2, 'dog', 65),

(3, 'pig', 21);

-- 插入测试

select * from goods;

select * from ord;

-- 下订单 ord (insert)

-- 常规操作

insert into ord values (123, 1, 2);

update goods set num=num-2 where gid=1;

-- 查看goods表2类商品数量是否变化 34=>32

select * from goods;

用触发器实现

drop trigger if exists t1;

delimiter //

create trigger t1

after

insert

on ord

for each row

begin

update goods set num=num-2 where gid=1;

end //

delimiter ;

-- test

show triggers \G;

\G 能显示详细, 但navicat不支持, 终端可以的 (直接复制终端的命令行, 代码块能自动格式美化)

xxxxxxxxxx

mysql> show triggers \G;

*************************** 1. row ***************************

Trigger: t1

Event: INSERT

Table: ord

Statement: begin

update goods set num=num-2 where gid=1;

end

Timing: AFTER

Created: 2019-10-01 23:14:55.08

sql_mode:

Definer: root@localhost

character_set_client: utf8mb4

collation_connection: utf8mb4_general_ci

Database Collation: utf8_general_ci

1 row in set (0.00 sec)

ERROR:

No query specified

x

-- test

select * from goods;

select * from ord;

-- 下订单, 目前有32只, 现再买2只

insert into ord values (124, 1, 2);

-- 查看goods表是否也跟着变更了

select * from goods;

输出如下

xxxxxxxxxx

mysql> select * from goods;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  32 |

|   2 | dog |  65 |

|   3 | pig |  21 |

+-----+------+-----+

3 rows in set (0.08 sec)

mysql> select * from ord;

+-----+-----+------+

| oid | gid | much |

+-----+-----+------+

| 123 |   2 |    2 |

| 123 |   1 |    2 |

+-----+-----+------+

2 rows in set (0.07 sec)

mysql> insert into ord values (125, 1, 2);

Query OK, 1 row affected (0.09 sec)

mysql> select * from goods;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  30 |

|   2 | dog |  65 |

|   3 | pig |  21 |

+-----+------+-----+

3 rows in set (0.07 sec)

局限性: update goods set num=num-2 where gid=1; 应该设置为变量才灵活. 即insert(被监视的语句), 产生的数据能否在触发器中引用到?

触发器引用行变量

下订单: 关键词: NEW

insert 操作时, 看作是NEW一个新行, new关键字, 即取到该行(类似对象)

xxxxxxxxxx

drop trigger if exists t2;

delimiter //

create trigger t2

after

insert

on ord

for each row

begin

update goods set num=num-NEW.much where gid=NEW.gid;

end //

delimiter ;

-- 查看已有 triggers: show triggers;

-- 删除已有 triggers: drop trigger [if exists] triggerName

-- test

select * from goods;

select * from ord;

-- 分别去购买1,2,3号商品, 对应的goods表也会发生变化

insert into ord values (128, 1, 3);

insert into ord values (130, 2, 5);

insert into ord values (131, 3, 1)

-- 查看数量是否改变

select * from goods;

效果:

mysql> select * from goods;

select * from ord;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  26 |

|   2 | dog |  65 |

|   3 | pig |  21 |

+-----+------+-----+

3 rows in set (0.06 sec)

+-----+-----+------+

| oid | gid | much |

+-----+-----+------+

| 123 |   2 |    2 |

| 123 |   1 |    2 |

| 125 |   1 |    2 |

| 126 |   2 |    5 |

| 127 |   1 |   10 |

+-----+-----+------+

5 rows in set (0.08 sec)

mysql> insert into ord values (128, 1, 3);

Query OK, 1 row affected (0.07 sec)

mysql> select * from goods;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  23 |

|   2 | dog |  65 |

|   3 | pig |  21 |

+-----+------+-----+

3 rows in set (0.07 sec)

mysql> insert into ord values (130, 2, 5);

Query OK, 1 row affected (0.05 sec)

mysql> select * from goods;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  23 |

|   2 | dog |  60 |

|   3 | pig |  21 |

+-----+------+-----+

3 rows in set (0.08 sec)

删订单: 关键词: OLD , 引用delete的行

曾经的一行old

x

drop trigger if exists t3;

delimiter //

create trigger t3

after

delete

on ord

for each row

begin

-- 删掉一条订单后, 对应的goods表应该对应增加该订单的数量

update goods set num=num+OLD.much where gid=OLD.gid;

end //

delimiter ;

效果如下

mysql> drop trigger if exists t3;

delimiter //

create trigger t3

after

delete

on ord

for each row

begin

-- 删掉一条订单后, 对应的goods表应该对应增加该订单的数量

update goods set num=num+OLD.much where gid=OLD.gid;

end //

delimiter ;

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.11 sec)

mysql> select * from ord;

+-----+-----+------+

| oid | gid | much |

+-----+-----+------+

| 123 |   2 |    2 |

| 123 |   1 |    2 |

| 125 |   1 |    2 |

| 126 |   2 |    5 |

| 127 |   1 |   10 |

| 128 |   1 |    3 |

| 130 |   2 |    5 |

| 131 |   3 |    1 |

+-----+-----+------+

8 rows in set (0.09 sec)

mysql> select * from goods where gid=2;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   2 | dog |  60 |

+-----+------+-----+

1 row in set (0.07 sec)

mysql> delete from ord where oid=123;

Query OK, 2 rows affected (0.10 sec)

mysql> select * from goods;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  25 |

|   2 | dog |  62 |

|   3 | pig |  20 |

+-----+------+-----+

3 rows in set (0.09 sec)

xxxxxxxxxx

drop trigger if exists t3;

delimiter //

create trigger t3

after

delete

on ord

for each row

begin

update goods set num=num+old.much where gid=old.gid

end //

delimiter ;

改订单 (数量) update : 结合old和new, 改之前是old, 改之后是new.

xxxxxxxxxx

delimiter //

create trigger t4

before

update

on ord

for each row

begin

update goods set num = num + old.much - new.much where gid = old.gid;

end //

delimiter ;

-- test

select * from goods;

select * from ord;

update ord set much=2 where gid=125;

x

-- 爆仓测试

delete from ord;

select * from goods;

-- 还剩21只pig, 现在买30只

insert into ord values (1, 3, 30);

select * from goods;

new & old

需求: 将30的数量改为10

原理: 先删掉30, 再加回10, 即先old, 再new.

x

mysql> select * from ord;

+-----+-----+------+

| oid | gid | much |

+-----+-----+------+

|   1 |   3 |   30 |

+-----+-----+------+

1 row in set (0.06 sec)

-- 在update之前(before)

drop trigger if exists t4;

delimiter //

create trigger t4

before

update on ord

for each row

begin

update goods set num=num+old.much - new.much where gid=old.gid;

end //

delimiter ;

xxxxxxxxxx

-- 爆仓演示

mysql> select * from goods;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  40 |

|   2 | dog |  72 |

|   3 | pig |  21 |

+-----+------+-----+

3 rows in set (0.05 sec)

mysql> insert into ord values (1, 3, 30);

Query OK, 1 row affected (0.05 sec)

mysql> select * from goods;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  40 |

|   2 | dog |  72 |

|   3 | pig | -9 |

+-----+------+-----+

3 rows in set (0.07 sec)

过程:

xxxxxxxxxx

mysql> drop trigger if exists t4;

delimiter //

create trigger t4

before

update on ord

for each row

begin

update goods set num=num+old.much - new.much where gid=old.gid;

end //

delimiter ;

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.12 sec)

mysql> select * from goods;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  40 |

|   2 | dog |  72 |

|   3 | pig | -9 |

+-----+------+-----+

3 rows in set (0.05 sec)

mysql> select * from ord;

+-----+-----+------+

| oid | gid | much |

+-----+-----+------+

|   1 |   3 |   30 |

+-----+-----+------+

1 row in set (0.06 sec)

-- 即 -9 + 30 -10 = 11

mysql> update ord set much=10 where oid=1;

Query OK, 1 row affected (0.05 sec)

Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from goods;

+-----+------+-----+

| gid | name | num |

+-----+------+-----+

|   1 | cat |  40 |

|   2 | dog |  72 |

|   3 | pig |  11 |

+-----+------+-----+

3 rows in set (0.07 sec)

Q1: before 与 afer 的而区别在哪?

Q2: 如何预防"爆仓"?

Q3: 在购买量 much > 库存量 num时, 把much自动改为num?

x

-- 在t2的基础上, 完成 much 与 num 的判断

drop trigger t5 if exists;

delimiter //

create trigger t5

after

inset

on ord

-- 声明变量用来存储查询到的剩余库存num值

declare rNum int;

for each row

begin

-- 查询到剩余库存

select num INTO rNum from goods where gid=NEW.gid;

-- if much > num 就爆仓了呀

if NEW.much > rNum

update goods set num=num-NEW.much where gid=NEW.gid

end //

delimiter ;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值