MySQL 返回更新值(RETURNING)

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

返回更新掉的行:

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

返回删除掉的行:

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

返回插入后的行:

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里如何实现呢? 
我可以创建几张内存表来来保存这些返回值,如下:

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 保存删除。

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

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 ;

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 ;

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 ;

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

我现在来演示:
更新:

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

获取更新记录:

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 |
+----+----------------------------+
3 rows in set (0.00 sec)

插入:

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)

获取插入记录:

mysql> select * from t1_insert;
+----+----------------------------+
| id | log_time                   |
+----+----------------------------+
|  1 | 2014-11-26 13:38:06.000000 |
+----+----------------------------+
1 row in set (0.00 sec)

删除:

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)

获取删除记录:

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 |
+----+----------------------------+
4 rows in set (0.00 sec)
时间: 2024-11-03 21:41:39

MySQL 返回更新值(RETURNING)的相关文章

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

在写SQL中,经常会有诸如更新了一行记录,之后要获取更新过的这一行. 本身从程序来说,没啥难度,大不了把这行缓存起来,完了直接访问. 但是从数据库的角度出发,怎么能快速的拿出来,而又不对原表进行二次扫描? 比如其他数据库提供了如下的语法来实现: 返回更新掉的行: t_girl=# update t1 set log_time = now() where id in (1,2,3) returning *;  id |          log_time           ----+------

mysql 批量更新与批量更新多条记录的不同值实现方法

在mysql中批量更新我们可能使用update,replace into来操作,下面来给各位详细介绍mysql 批量更新与性能吧! mysql更新语句很简单,更新一条数据的某个字段,一般这样写: 复制代码代码如下: UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value'; 如果更新同一字段为同一个值,mysql也很简单,修改下where即可: 复制代码代码如下: UPDATE mytable SET myfie

mysql如何更新一个表中的某个字段值等于另一个表的某个字段值

update a inner join b on a.bid=b.id set a.x=b.x,a.y=b.y ; 这里使用了case when 这个小技巧来实现批量更新.举个例子: 1 2 3 4 5 6 7 UPDATE categories     SET display_order = CASE id         WHEN 1 THEN 3         WHEN 2 THEN 4         WHEN 3 THEN 5     END WHERE id IN (1,2,3)

转: MYSQL获取更新行的主键ID

在某些情况下我们需要向数据表中更新一条记录的状态,然后再把它取出来,但这时如果你在更新前并没有一个确认惟一记录的主键就没有办法知道哪条记录被更新了. 举例说明下: 有一个发放新手卡的程序,设计数据库时常见的方案有两种: 方案一:使用一张表,新手卡和领取记录都在一起,这样主要字段就是新手卡(主键).用户ID(惟一).领取状态(非必要)等 这样的话数据库操作就简单了,直接一条update sql,将用户id更新到这张表里,然后根据用户ID再select出来就好了.但这样记录很多时就会有效率的问题,暂

如何实现MySQL随机查询数据与MySQL随机更新数据?

以下的文章主要介绍的是MySQL随机选取数据,对实现MySQ随机查询数据与MySQ随机更新数据的实际操作步骤的描述,以及对其实际操作中所要用到的语句的描述,以下就是对其具体操作步骤的描述. MySQL随机查询数据 以前在群里讨论过这个问题,比较的有意思.mysql的语法真好玩.他们原来都想用PHP的实现随机,但取出多条好像要进行两次以上查询.翻了手册,找到了下面这个语句,可以完成任务了. SELECT * FROM table_name ORDER BY rand() LIMIT 5; MySQ

mysql并发更新

mysql并发更新 常见方案 乐观锁 select * from tab1 where id = ?; update tab1 set col1 = ? where id = ? and version = ?; 缺点 在高并发下可能更新失败,所以需要通过重试(select...,update...)来提高更新成功率 读取锁定MySQL 8.0 Reference Manual / ... / Locking Reads select * from tab1 where id = ? for u

MySQL表更新操作

1.  使用insert语句向表插入一条新记录,语法是:insert into 表名 [(字段列表)] values(值列表). 2.  使用set 语句更新操作与字符集,例如setcharacter_set_client =latin1\gbk\utf8; 3.  使用delete语句删除表记录,例如delete from 表名 where 条件表达式: 4.  使用insert语句可以一次性地向表中批量插入多条记录,语句是:insert  into 表名 [(字段名)]values (值列表

MyBatis+MySQL 返回插入记录的主键ID

今天用到了多个表之间的关系,另一个表中的一个字段要以第一个表的主键作为外键. 下面说两种方法,MyBatis+MySQL 返回插入记录的主键ID: 第一种: <insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="userId" parameterType="com.chenzhou.mybatis.User"> insert into us

mysql查询更新时的锁表机制分析(只介绍了MYISAM)

为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级.MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking):BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁:InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁. MySQL这3种锁的特性可大致归纳如下: 表级锁:开销小,加