【SQL標準中有一個叫同時執行的概念】html
同時執行指的是在同一個子句中的各個部分的執行時機是不區分前後的,以下面的SQL語句mysql
select abs(-1),abs(2); +---------+--------+ | abs(-1) | abs(2) | +---------+--------+ | 1 | 2 | +---------+--------+ 1 row in set (0.01 sec)
按SQL標準的說法 abs(-1) 與 abs(2) 這兩個函數是「同時執行」的!sql
【MySQL的Update與SQL標準相背】數據庫
1): 爲了說明問題我定義以下表結構,表t包含兩個數據列`x`,`y`函數
create table t(id int not null auto_increment primary key, x int, y int);
2): 給表t增長一行數據url
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語句spa
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」;.net
若是你以爲這樣的結果對你來講沒有問題,那咱們來看下一個update語句,我只是把「x=x+1」和「y=x」這兩個部分交換一下。code
4): 執行調整後的SQL語句htm
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-------------------------------------------------