DML觸發器的缺憾

2021-08-27 09:16:45 字數 1679 閱讀 5920

tom說過他希望三樣東西不曾存在:觸發器,自治事務,when others

級聯刪除、級聯修改,在設計良好的系統中是不存在的

即使有,那也是小概率事件,必須專門寫一段指令碼來解決,而不是作為常規功能存在

不得不用觸發器,要麼是原系統模組化做得不夠好,要麼是不允許改動原有的**

當然有時候不是不允許,而是風險太大

每個觸發器都是乙個隱藏的儲存過程。隱藏的**對開發者很不友好

如果你正在看一段別人的程式,總覺得少了點什麼,折騰半天原來還有些動作隱藏在觸發器裡!

順藤摸瓜去找了觸發器,發現裡面對其他表有dml,又有其他隱藏**,是不是頭很大?

這種連鎖觸發增加了複雜性,很容易失控。起初我也做過這種東西,覺得系統布滿了精巧的機關,很有成就感

後來才發現這對維護來說簡直就是噩夢加陷阱

因為觸發器是隱藏的,它不執行你也不知道。假如有個觸發器編譯失效,dml還是不聲不響的照樣成功了!儲存過程就不會這樣

觸發器沒有辦法繞過。假如你有個產品正在跑,這時候需要補幾條故障時間的歷史資料,insert上的觸發器有些動作是你不想要的

這就難辦了。

觸發器還有mutating table問題。很多人一看這問題就上自治事務,殊不知這是個餿主意

自治事務使得你看到的資料都是舊的,因為主事務所作的修改還未提交

多行的dml會多次觸發,產生一大堆小事務,很容易發生死鎖

在批量操作、多次觸發的情況下,觸發器的效率低,因為它相當於每次都執行一段pl/sql

往往可以把它轉化為等價的幾個sql,效率提高很多

觸發器是對某種事件發生時的響應,共有5種不同型別的事件可以掛載觸發器**

在觸發器中所做的一切,都處於開發的盲點之中,這是個後患

trigger裡面的sql會被重複軟解析,plsql的游標快取不起作用了

即使要用觸發器,也要把裡面的**轉移出來做成儲存過程,然後在觸發器裡呼叫儲存過程

如果是行級的觸發器,更新哪行就在哪行觸發;如果是語句級的,整個update只觸發一次

update語句是隱式游標,和你自己用游標逐條更新的效果一樣但效能更好

下面是dml觸發器令人深惡痛絕的三個實際案例:

㈠如果嘗試到乙個不熟悉的專案做一下維護,就會對這種情況深惡痛絕

曾經一次為了找乙個bug,花了兩天時間

最後發現,另外乙個不是很相干的表,上面建了乙個觸發器對相關的表進行了更新

而這個觸發器上有個bug

㈡有次維護系統,程式基本都是寫在form裡面的。結果發現一執行就會莫名其妙的更改掉表的乙個值

害的我只好一點點mark,一段段的測試,最後發現是對錶insert的時候會更改。是表的trigger做怪

㈢最近俺查詢乙個問題, 總覺得是user操作的問題導致, 檢視 form 程式沒有異樣, 但是儲存的資料就是不對

好不容易查到不知是誰在db端增加了乙個觸發器, 害我好難找

user提出問題時我沒有實測, 只是檢查前端form**, 其中有關於user提到問題的邏輯

所以我怎麼也沒有想到db中誰又寫了個新的邏輯來覆蓋了form中的邏輯. 真是鬱悶壞了....

如果 form 中沒有那段邏輯, 我還會很自然的想到可能是 db 中有觸發器. 可偏偏 form 中有那段邏輯, 奶奶的

當然啦,dml觸發器的存在必定有其存在的優點

使用觸發器後可能帶來的麻煩, 我想這應該作為開發人員在要寫觸發器的時候需要考慮的因素.並不應該作為摒棄觸發器的原因

DML觸發器觸發順序

dml觸發器觸發時,dml語句的執行順序 1 語句之前級觸發器 2 行之前級觸發器 3 語句本身 4 行之後級觸發器 5 語句之後級觸發器 例如對錶table new進行更新,使用臨時表記錄觸發器的激發順序,如 所示 語句之前級觸發器 create or replace trigger bstate...

DDL觸發器與DML觸發器比較

dml觸發器 要防止對資料庫架構進行某些更改。希望資料庫中發生某種情況以響應資料庫架構中的更改。要記錄資料庫架構中的更改或事件。僅在執行觸發 ddl 觸發器的 ddl 語句後,ddl 觸發器才會激發。ddl 觸發器無法作為 instead of 觸發器使用。下面的示例顯示如何使用 ddl 觸發器阻止...

Oracle中的DML觸發器

什麼是dml觸發器?dml觸發器是指基於dml操作所建立的觸發器.dml操作 select update insert delete,用來對資料庫裡的資料進行操作 dml觸發器的作用?dml觸發器可用於實現資料安全保護 資料審計 資料完整性 參照完整性 資料複製等功能.dml觸發器型別?1.語句觸發...