【SQL标准中有一个叫同时执行的概念】
同时执行指的是在同一个子句中的各个部分的执行时机是不区分先后的,如下面的SQL语句
select abs(-1),abs(2); +---------+--------+ | abs(-1) | abs(2) | +---------+--------+ | 1 | 2 | +---------+--------+ 1 row in set (0.01 sec)
按SQL标准的说法 abs(-1) 与 abs(2) 这两个函数是“同时执行”的!
【MySQL的Update与SQL标准相背】
1): 为了说明问题我定义如下表结构,表t包含两个数据列`x`,`y`
create table t(id int not null auto_increment primary key, x int, y int);
2): 给表t增加一行数据
insert into t(x,y) values(1,1); select * from t; +----+------+------+ | id | x | y | +----+------+------+ | 1 | 1 | 1 | +----+------+------+ 1 row in set (0.00 sec)
3): 执行一条update语句
update t set x=x+1 ,y=x; select * from t; +----+------+------+ | id | x | y | +----+------+------+ | 1 | 2 | 2 | +----+------+------+ 1 row in set (0.00 sec)
从上面的结果可以看出update语句不是同时执行的,如果按同时执行的理论y=x这个语句执行时x的值还会是初始的值“1”而不是自增后的值“2”;
如果你觉得这样的结果对你来说没有问题,那我们来看下一个update语句,我只是把“x=x+1”和“y=x”这两个部分交换一下。
4): 执行调整后的SQL语句
update t set y=x, x=x+1; mysql> select * from t; +----+------+------+ | id | x | y | +----+------+------+ | 1 | 3 | 2 | +----+------+------+ 1 row in set (0.00 sec)
可以看到MySQL数据库中的update并不是同时执行的,它是有先后次序的,而这个先后次序会直接影响到你执行SQL的结果
【总结】
编写程序时就要意识到MySQL在处理update语句特殊性,前面执行的赋值语句会对后台的语句产生影响;最后这个并不是一个bug,之所以这么
说是因为MySQL在其官方文档中明确的提到了这一点,在这个Bug算Future的年代;我们也只能说这个是对SQL标准的一个变通吧。
官方文档:https://dev.mysql.com/doc/refman/8.0/en/ansi-diff-update.html
-----------------------------http://www.sqlpy.com-------------------------------------------------
-----------------------------http://www.sqlpy.com-------------------------------------------------