MySQL update 語句與標準SQL不同的地方
【SQL標準中有一個叫同時執行的概念】
同時執行指的是在同一個子句中的各個部分的執行時機是不區分先後的,如下面的SQL語句
select abs(-1),abs(2); +---------+--------+ | abs(-1) | abs(2) | +---------+--------+ | 1 | 2 | +---------+--------+ 1 row in set (0.01 sec)
按SQL標準的說法 abs(-1)
【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-------------------------------------------------
MySQL update 語句與標準SQL不同的地方