今天偶然想起一個UPDATE相關的小問題,正常情況下,如果我們將UPDATE改寫成與之對應的SELECT語句,其SELECT查詢結果應與UPDATE的目標表存在一對一的關系,例如:
對于UPDATE語句:
UPDATE TB1 SET C2=TB2.C2 FROM TB1 INNER JOIN TB2 ON TB1.C1=TB2.C1
假設TB1中C1為主鍵,那么改寫成對應的SELECT SQL
SELECT TB1.C1,TB1.C2 AS C2_OLD,TB2.C2 AS C2_NEWFROM TB1 INNER JOIN TB2 ON TB1.C1=TB2.C1
以上查詢結果應該也可以以C1為主鍵,即C1在此查詢結果中是唯一的。
問題出現了,如果查詢結果中C1不唯一,那么更新后的結果會是什么呢?
讓我們來測試下,準備測試數據:
CREATE TABLE TB001( C1 INT, C2 INT);GOCREATE TABLE TB002( C1 INT, C2 INT);DELETE FROM TB001DELETE FROM TB002INSERT INTO TB001(C1,C2)SELECT 1,1UNION ALLSELECT 2,1GOINSERT INTO TB002(C1,C2)SELECT 1,3UNION ALLSELECT 1,2UNION ALLSELECT 2,4GOSELECT * FROM TB001SELECT * FROM TB002GOSELECT *FROM TB001 T1 INNER JOIN TB002 T2ON T1.C1=T2.C1
查詢結果中C1的記錄并不唯一,如果我們對此更新,結果會是什么呢?
UPDATE方式1
--第一種更新UPDATE TB001SET C2=T1.C2*T2.C2FROM TB001 T1 INNER JOIN TB002 T2ON T1.C1=T2.C1--查看執行結果SELECT * FROM TB001
UPDATE方式2
--第二種更新UPDATE TB001SET C2=TB001.C1*T2.C2FROM TB002 T2WHERE TB001.C1=T2.C1--查看執行結果SELECT * FROM TB001
UPDATE方式3
--第三種更新WITH TMP AS( SELECT T1.C1,T1.C2,T1.C2*T2.C2 AS NewC2 FROM TB001 T1 INNER JOIN TB002 T2 ON T1.C1=T2.C1)UPDATE TMPSET C2=NewC2--查看執行結果SELECT * FROM TB001
通過比較,不難看出,對于第一種和第三種方式,TB001中的C1=1的記錄只被更新1次,而對于第二種方式來說,該記錄被更新2次。
---====================================================================
對于上面的例子,無論那種方式,更新結果都可能不是我們預期的結果,因此我們避免此類操作(尤其是生產環境)。
盡管這些測試沒有太多意義,但聊勝于無,供各位看官一看。
BTW:對于三種UPDATE寫法,個人偏好第三種,因為可以很容易滴查看SELECT結果集,從而對更新后的結果有一個預期了解,以檢查是否滿足需求。
--====================================================================
很多人是來看妹子的,我懂你們的。。。
重口難調,你們將就下
新聞熱點
疑難解答