5 個你不該使用 Stored Procedure 的原因

Simiao Chen
5 min readAug 4, 2020

--

這篇文章主要是寫給對 Stored Procedure 已經有基本了解的觀眾,如果你還不知道 Stored Procedure 是什麼,請先參考 wikitutorial

至於 Stored Procedure 的鐵粉別急著走,給我一首歌的時間說清楚講明白

碰到 SP 時我都是這個臉 !!

NOTE: 以下 Stored Procedure 簡稱為 SP

理由 1 : 實在太難閱讀了 !

想像一下,如果打開一個 SP 檔案,發現裡面有 1000 行 SQL。裡面有各種 SELECT / UPDATE / INSERT / JOIN,有時候還用 IF 判斷要不要執行某段SQL ,時不時在來 TRY CATCH 一下,是不是很崩潰 !

多數情況下,1000 行的程式碼絕對會比 1000 行的 SQL 好理解很多。因為大部分對資料庫做 CRUD 的操作的 function 命名都有類似的規則,比如一看到 findXXXById() 或 updateXXXById() 就大概能猜到這個 function 的功能,比起閱讀 SELECT field1, field1… WHERE…肯定會容易許多。

如果只有兩三條 SQL當然不會有感覺,但如果是兩三千行的話,簡直欲哭無淚 !

理由 2 : Debug 困難 !

少了IDE 下斷點來 trace code, 讓 debug 難度一下子突破天際 !

不像使用 debug mode 可以及時讓你知道每行程式執行完會有什麼結果,SP 中每句 SQL 都必須手動執行看看,不然很難用肉眼判斷到底哪些資料有被 SELECT 出來哪些沒有;又或者是這個 IF 判斷式到底為 true or false。

理由 3 : 資料庫移植性差 !

這個不用多說,全部 SQL 重寫 !!!

不過不只 SP 啦,只要是手寫 raw SQL 都有這個缺點。

理由 4 : 修改成本大

資料表欄位或 SP 本身的 INPUT 有變動的話會造成大悲劇。

假設今天要把某個資料表中 is_deleted 這個欄位的型態從 small int 調整成 varchar ,或者刪除 user_name 這個欄位好了,你必須用 IDE 全域搜尋所有有使用到這個欄位的 SP,並對其做相應的修改。如果這個資料表或欄位頻繁出現在各個 SP 中,同一個 SP 中還使用好幾次且分別散落在那 3000行的SQL 裡面,工程師真的有得忙了! 但如果平常是使用物件將資料表對應的欄位封裝起來,只需要改一次相對應的物件即可。

理由 5 : 非 Checked exception

你的 IDE 檢查不到,你的 CI/CD 工具也檢查不到呦

假設你像上一點這樣需要修改欄位或 INPUT 參數;用物件封裝的話,如果改掉型態,移除變數或者 function 的 input / output 改變了,IDE 馬上會紅成一片給你看,只要照它報錯的地方修改基本不會有太大問題。

把特,就是這個把特!! SP 的正確性與否,並不是 checked exception 所以 IDE 檢查不到,一切都只能你自己來了。於是你費盡千辛萬苦終於把搜尋到的 20支相關的 SP 都改好,但緊接在後的是需要測試更多有用到這些 SP 的 function。因為 SP 造成的錯誤通常是 runtime exception,也就是使用到了那支 function 時才會出錯。大概就像蒙著眼參加越野機車比賽一樣,坑很多而且永遠不知道會在哪裡跌倒啊 !

有寫單元測試的話是還好;如果沒有的話,你有以下3 種選擇 ~

(1) 花大量時間手動測試所有使用到相關 SP 的 function (但老闆會來關心你改一個欄位為何需要那麼久)。

(2) 乾脆不測試跟他賭改完以後沒問題。(這跟踩地雷一樣,雖然是 user 踩,但被炸的是你)。

(3) 開始寫離職信 (誤)

雖然花了很長的的篇幅在描述 SP 有多雷,但它還是有派得上用場的地方啦 ~

適合的使用場景

  • 跨多個資料表的簡單查詢,但不包含業務邏輯。
  • INSERT LOG 這種簡單的資料插入
  • 寫好以後直到天荒地老都不太可能改動的東西。
  • 專案趕死線,擴充跟維護什麼的於我如浮雲 (菸)
  • 你真的非常想陷害接手的人 (誤)

不適合的使用場景

  • 業務邏輯寫在 SP 裡面母湯 !!
  • 除了剛剛說適合的以外全部都不適合 !!

結語

雖然這是一篇勸世文,但老實說我完全同意 SP 寫起來真的是有它的爽度在。

尤其是跨多個資料表查詢時,全部寫在一起一次 return 給我非常痛快啊! 省的拆好幾支 function 還散落在不同 DAO,全部都查回來以後還要用程式把它們拼拼湊湊起來。但如整篇所說,SP 如果在胡亂使用 / 過度使用,將會造維護及擴充上的大災難,這不就先甘後苦了嗎?

一個技術並不是非黑即白,端看它用在哪裡及解決什麼問題。

這篇勸世文不是要嚇大家說 SP 有多可怕,而是希望下次要想要使用 SP 時可以深呼吸多想一下,這裡適合用嗎 ? 這樣用的話之後會不會有擴充跟維護問題呢 ? 正確的使用 SP 是珍惜生命的一種方式之一。

謝謝你看到最後,有任何想法都歡迎留言討論,一起切磋成長。

如果這篇文章有幫助的話,記得幫我拍個手。

好的,那今天就說到這邊,我們下回見~ PEACE

--

--