博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于update语句返回的影响行数
阅读量:6142 次
发布时间:2019-06-21

本文共 2446 字,大约阅读时间需要 8 分钟。

hot3.png

今天很忙,本来想存成草稿有空在编辑的。结果一不小心发布了,所以只能先写完了。

先描述下背景,一个提问的问题

以前我认为,只要是update的where条件可以找到数据的,那么返回的影响行数必然是大于0的。

写了一个SQL: UPDATE tss_view_template SET name='默认风格' where id=1; 结果返回影响行数是0,但是SQL变成这样: UPDATE tss_view_template SET name='默认风格',gmt_create=now() where id=1; 结果返回影响行数是1 难道说这条update的执行之前,会先比对你要更新的字段,如果是一样的,就不算是更新 还是说这个是MySQL的特性

把这个问题简单的归纳下就是,updae语句如果不实际改变数据,那么会不会在底层做操作?

于是在本地做了一下测试

mysql> update test set a=1 where b=2;Query OK, 0 rows affectedRows matched: 1  Changed: 0  Warnings: 0mysql> select row_count();+-------------+| row_count() |+-------------+|           0 |+-------------+1 row in setmysql> update test set a=2 where b=2;Query OK, 1 row affectedRows matched: 1  Changed: 1  Warnings: 0mysql> select row_count();+-------------+| row_count() |+-------------+|           1 |+-------------+1 row in setmysql> select version();+-----------+| version() |+-----------+| 5.5.15    |+-----------+1 row in set
我的测试环境是mysql5.5.15,其中row mathc和row change却是和问题中的描述一样。我们主要关注一下change这个数列

另外我再实验中使用了select row_count这个函数,可以看到这个值和change是一致的。

关于row_count这个函数,我们可以参考一下mysql的文档 ,mysql的官方文档上是这么写的“For UPDATE statements, the affected-rows value by default is the number of rows actually changed. If you specify the CLIENT_FOUND_ROWS flag to mysql_real_connect() when connecting to mysqld, the affected-rows value is the number of rows “found”; that is, matched by the WHERE clause.” 也就是说是默认情况下是actually影响的值,但是在mysql启动的时候改变下CLIENT_FOUND_ROWS这个值的话就是“发现的值”而不是“改变的值”。下面是参考文档的原文

另外关于row_count这个问题 有人在stackoverflow中提过相似的问题。意思是这个好像和mysql的版本有关,见下面的连接

但是我特意在5.1上做了这个实验,并没有复现这个问题。下面是我在本地的实验截图

mysql究竟是怎么做的呢?

有两个值。 Rows matched和Changed 前者表示匹配的行数,后者表示改变的行数。 如果update语句没有对数据做出修改,则changed为0,如果有一行匹配的记录的话,Rows matched为1 
在进入Innodb层时,会判断是否做出修改,ha_innobase::update_row->calc_row_difference 不过从代码的逻辑来看,即使需要更新的字段数为0,还是会跑到更新记录的逻辑,只是没有修改任何数据而已 
例如 mysql> create table x1 (a int, b int); Query OK, 0 rows affected (0.00 sec) 
mysql> insert into x1 values (1,2),(2,3); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 
mysql> update x1 set a=1 where b =2; Query OK, 0 rows affected (0.00 sec) Rows matched: 1 Changed: 0 Warnings: 0 
mysql> update x1 set a=12 where b =2; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0

可以参考这个mysql的文档

 mysql是这样的,那么oracle对于update相同的行时又是怎么做的呢?

这里我就不做实验了,参考一个网上的博客,得到的结论就是oracle在处理相同行的时候会是会做更新操作的。

总结一下,msyql在update相同的行的时候是不会做change操作的,而oracle是会记录这个行的。

转载于:https://my.oschina.net/zimingforever/blog/83810

你可能感兴趣的文章
[Git] git merge之squash
查看>>
C++/CLI
查看>>
Kerberos安全体系详解---Kerberos的简单实现
查看>>
Vuex demo
查看>>
新建swap分区的规划、挂载和自动挂载示例
查看>>
MySQL用户授权【转】
查看>>
我算是优秀的程序员吗?
查看>>
链表合并
查看>>
Delphi应用程序的调试(五)其他调试工具
查看>>
如何编写可维护的面向对象JavaScript代码
查看>>
win8: html5+css3+js
查看>>
Emacs 24.3支持cygwin上使用Win32 GUI
查看>>
对于一个排序数组,创建最低高度的Binary Tree
查看>>
Android-----判断是否有服务运行
查看>>
poj2392 Space Elevator(多重背包)
查看>>
oracle中恢复删除的表
查看>>
宏定义和内联函数
查看>>
设计一个栈,设计一个max()函数,求当前栈中的最大元素
查看>>
PHP 中的超全局变量
查看>>
WPF Converter 使用复杂参数的方法
查看>>