1. 程式人生 > 實用技巧 >SpringBoot - 10異常處理與單元測試

SpringBoot - 10異常處理與單元測試

此文轉載自:https://blog.csdn.net/weixin_39540651/article/details/112259645

當我們在資料庫中有這樣的需求時:
需要以某列的當前值為判斷物件,將其更新成其它值。

例如下面一張表:

        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的多版本特性有關。不過一般需要進行這種主鍵的調換的時候,我們可以先禁用掉約束即可。