當我們在資料庫中有這樣的需求時:
需要以某列的當前值為判斷物件,將其更新成其它值,
例如下面一張表:
ID INFO
---------- ----------
2 a
1 b
3 c
4 d
5 e
我們最簡單的方式就是通過多個update來完成:
update t1 set id= 2
where id = 1;
update t1 set id = 1
where id = 2;
......
看上去很簡單,但是上面的更新卻存在一個很大的問題,當我們第一次執行完update后,表中id=2其實有兩行資料,再去進行第二條陳述句時,兩條陳述句將都會被更新,
顯然這些并非我們的意愿,我們僅僅是希望id=1和id=2的值互換,
為了避免這個問題,我們可以使用case運算式來進行批量更新,
SQL> update t1
2 set id = case when id = 1
3 then 2
4 when id = 2
5 then 1
6 else id end;
5 rows updated.
SQL> select * from t1;
ID INFO
---------- ----------
2 a
1 b
3 c
4 d
5 e
這樣不僅執行正確,而且只需要執行一次,自然更加高效,這個寫法應用范圍很廣,例如我們可以很輕松實作主鍵值之間的互換,否則我們需要執行3次update才可以完成,
PostgreSQL差異點:
需要注意的是,在pg中使用該方法會因為主鍵重復而報錯,
bill@bill=>update t2
set id = case when id = 1
then 2
when id = 2
then 1
else id end;
ERROR: duplicate key value violates unique constraint "t2_pkey"
DETAIL: Key (id)=(2) already exists.
但是,約束的檢查應該是在更新完成后執行,所以在更新的程序中主鍵值出現重復應該沒問題,
所以在Oracle中執行正常,
當然在pg中存在這種問題主要還是和pg的多版本特性有關,不過一般需要進行這種主鍵的調換的時候,我們可以先禁用掉約束即可,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/245738.html
標籤:其他
