【原创】MySQL 返回更新值(RETURNING)

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介:

在写SQL中,经常会有诸如更新了一行记录,之后要获取更新过的这一行。 本身从程序来说,没啥难度,大不了把这行缓存起来,完了直接访问。 但是从数据库的角度出发,怎么能快速的拿出来,而又不对原表进行二次扫描? 比如其他数据库提供了如下的语法来实现:


返回更新掉的行:

1
2
3
4
5
6
7
8
9
t_girl=#  update  t1  set  log_time = now()  where  id  in  (1,2,3) returning *;
  id |          log_time          
----+----------------------------
   1 | 2014-11-26 11:06:53.555217
   2 | 2014-11-26 11:06:53.555217
   3 | 2014-11-26 11:06:53.555217
(3  rows )
UPDATE  3
Time : 6.991 ms


返回删除掉的行:

1
2
3
4
5
6
7
t_girl=#  delete  from  t1  where  id < 2 returning *;
  id |          log_time          
----+----------------------------
   1 | 2014-11-26 11:06:53.555217
(1 row)
DELETE  1
Time : 6.042 ms


返回插入后的行:

1
2
3
4
5
6
7
8
t_girl=#  insert  into  t1  select  1,now() returning *;
  id |          log_time          
----+----------------------------
   1 | 2014-11-26 11:07:40.431766
(1 row)
INSERT  0 1
Time : 6.107 ms
t_girl=#



那在MySQL里如何实现呢? 

我可以创建几张内存表来来保存这些返回值,如下:

1
2
3
4
5
6
CREATE  TABLE  t1_insert ENGINE MEMORY  SELECT  FROM   t1  WHERE  FALSE ;
CREATE  TABLE  t1_update ENGINE MEMORY  SELECT  FROM   t1  WHERE  FALSE ;
CREATE  TABLE  t1_delete ENGINE MEMORY  SELECT  FROM   t1  WHERE  FALSE ;
ALTER  TABLE  t1_insert  ADD  PRIMARY  KEY  (id);
ALTER  TABLE  t1_update  ADD  PRIMARY  KEY  (id);
ALTER  TABLE  t1_delete  ADD  PRIMARY  KEY  (id);


以上建立了三张表来存放对应的操作。 t1_insert 保存插入;t1_update 保存更新;t1_delete 保存删除。


那这样的话,我来创建对应的触发器完成。


1
2
3
4
5
6
7
8
9
10
11
DELIMITER $$
USE `t_girl`$$
DROP  TRIGGER  /*!50032 IF EXISTS */ `tr_t1_insert_after`$$
CREATE
     /*!50017 DEFINER =  'root' @ 'localhost'  */
     TRIGGER  `tr_t1_insert_after`  AFTER  INSERT  ON  `t1` 
     FOR  EACH ROW  BEGIN
       REPLACE  INTO  t1_insert  VALUES  (new.id,new.log_time);
     END ;
$$
DELIMITER ;


1
2
3
4
5
6
7
8
9
10
11
DELIMITER $$
USE `t_girl`$$
DROP  TRIGGER  /*!50032 IF EXISTS */ `tr_t1_update_after`$$
CREATE
     /*!50017 DEFINER =  'root' @ 'localhost'  */
     TRIGGER  `tr_t1_update_after`  AFTER  UPDATE  ON  `t1` 
     FOR  EACH ROW  BEGIN
       REPLACE  INTO  t1_update  VALUES  (new.id,new.log_time);
     END ;
$$
DELIMITER ;


1
2
3
4
5
6
7
8
9
10
11
DELIMITER $$
USE `t_girl`$$
DROP  TRIGGER  /*!50032 IF EXISTS */ `tr_t1_delete_after`$$
CREATE
     /*!50017 DEFINER =  'root' @ 'localhost'  */
     TRIGGER  `tr_t1_delete_after`  AFTER  DELETE  ON  `t1` 
     FOR  EACH ROW  BEGIN
       REPLACE  INTO  t1_delete  VALUES  (old.id,old.log_time);;
     END ;
$$
DELIMITER ;


创建好了以上的表和触发器后, 拿到返回值就非常容易了, 我直接从以上几张表来查询就是。


我现在来演示:

更新:

1
2
3
4
5
mysql>  truncate  table  t1_update;
Query OK, 0  rows  affected (0.00 sec)
mysql>  UPDATE  t1  SET  log_time = NOW()  WHERE  id < 15;
Query OK, 3  rows  affected (0.01 sec)
Rows  matched: 3  Changed: 3  Warnings: 0

获取更新记录:

1
2
3
4
5
6
7
8
9
mysql>  select  from  t1_update;
+ ----+----------------------------+
| id | log_time                   |
+ ----+----------------------------+
| 12 | 2014-11-26 13:38:06.000000 |
| 13 | 2014-11-26 13:38:06.000000 |
| 14 | 2014-11-26 13:38:06.000000 |
+ ----+----------------------------+
rows  in  set  (0.00 sec)


插入:

1
2
3
4
mysql>  truncate  table  t1_insert;
Query OK, 0  rows  affected (0.00 sec)
mysql>  INSERT  INTO  t1  VALUES  (1,NOW());
Query OK, 1 row affected (0.08 sec)

获取插入记录:

1
2
3
4
5
6
7
mysql>  select  from  t1_insert;
+ ----+----------------------------+
| id | log_time                   |
+ ----+----------------------------+
|  1 | 2014-11-26 13:38:06.000000 |
+ ----+----------------------------+
1 row  in  set  (0.00 sec)


删除:

1
2
3
4
mysql>  truncate  table  t1_delete;
Query OK, 0  rows  affected (0.00 sec)
mysql>  DELETE  FROM  t1  WHERE  id < 15;
Query OK, 4  rows  affected (0.01 sec)

获取删除记录:

1
2
3
4
5
6
7
8
9
10
mysql>  select  from  t1_delete;
+ ----+----------------------------+
| id | log_time                   |
+ ----+----------------------------+
|  1 | 2014-11-26 13:38:06.000000 |
| 12 | 2014-11-26 13:38:06.000000 |
| 13 | 2014-11-26 13:38:06.000000 |
| 14 | 2014-11-26 13:38:06.000000 |
+ ----+----------------------------+
rows  in  set  (0.00 sec)





本文转自 david_yeung 51CTO博客,原文链接:http://blog.51cto.com/yueliangdao0608/1584932 ,如需转载请自行联系原作者
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
关系型数据库 MySQL Java
MySQL 巨坑:update 更新慎用影响行数做判断!!!
MySQL 巨坑:update 更新慎用影响行数做判断!!!
2262 0
MySQL 巨坑:update 更新慎用影响行数做判断!!!
|
SQL 关系型数据库 MySQL
mysql实战:左表数据全部展示,关联表有关联数据返回1,没有关联数据返回0
现在有一消息通知功能,后台发布的每条通知消息都会展示到APP端消息列表中,每条消息支持是否已读操作,从消息列表中点击进入详情视为完成已读操作;现在需要在查询出的用户消息列表信息,其中所有的通知消息信息要标注出是否已读.
mysql实战:左表数据全部展示,关联表有关联数据返回1,没有关联数据返回0
|
SQL 关系型数据库 MySQL
MySql 使用 NOT IN 返回值包含null值,返回数据不全
MySql 使用 NOT IN 返回值包含null值,返回数据不全
462 0
MySql 使用 NOT IN 返回值包含null值,返回数据不全
|
关系型数据库 MySQL
MySQL基础-删除/更新行为
添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除/更新行为。具体的删除/更新行为有以下几种:
349 0
|
存储 SQL 关系型数据库
Mysql-一条更新语句要经历那些流程
Mysql-一条更新语句要经历那些流程
Mysql-一条更新语句要经历那些流程
|
SQL 关系型数据库 MySQL
mysql中case when返回多个字段处理方案
一般情况下case when结构,返回的字段只能支持一个,但是会有很多业务场景中需要返回一个以上字段信息.这种问题有两个处理方案,一个是将case when结构进行改造,支持返回多个字段;另一种就是保持case when返回字段个数不变(只返回一个字段),修改业务逻辑,在service中按照case when返回一个字段进行处理.本文主要介绍第一种处理方案.下面结合一个业务场景说明如何进行处理.
|
SQL 关系型数据库 MySQL
MYSQL查询近一年 近一月 近一周 今天数据 没有数据返回0 按时间有序返回数据
MYSQL查询近一年 近一月 近一周 今天数据 没有数据返回0 按时间有序返回数据
886 0
MYSQL查询近一年 近一月 近一周 今天数据 没有数据返回0 按时间有序返回数据
|
SQL 关系型数据库 MySQL
【MySQL作业】DDL 和 DML——美和易思使用 DML 新增和更新表数据应用习题
【MySQL作业】DDL 和 DML——美和易思使用 DML 新增和更新表数据应用习题
259 0
【MySQL作业】DDL 和 DML——美和易思使用 DML 新增和更新表数据应用习题
|
关系型数据库 MySQL
MySQL插入、更新、删除数据
MySQL插入、更新、删除数据
200 0
MySQL插入、更新、删除数据
|
关系型数据库 MySQL 索引
mysql更新varchar类型字段长度报错:ERROR 1074 (42000): Column length too big for column ‘value‘ (max = 21845);
mysql更新varchar类型字段长度报错:ERROR 1074 (42000): Column length too big for column ‘value‘ (max = 21845);

推荐镜像

更多