為了保證資料庫的完整性和一致性,很多的時候需要執行多條sql語句才能達到想要的目的。
在一對多的資料庫關係中,比如卡號類別與卡號之間的關係。如果要取消某個類別的時候,就要連同齊下的所有卡號都刪除。在現實中,註冊的時候一般都會進行充值,當我想card表裡面寫東西的時候,就要向recharge表裡面寫一條充值記錄。完成這兩個操作才算完成這個功能的實現.
對於以上的需求,每個功能的實現都伴隨著多條sql語句的執行。
為瞭解決上面的問題,一共有兩種解決方案。一是預存程序,二是觸發器。上篇部落格中已經講解了預存程序。那麼這篇部落格當然要來詳解一下觸發器了。
觸發器:當發生某個操作之後進行的一系列操作。
資料庫中除了查詢之外就只有增刪改三種操作了。所以觸發器就分為三類:insert、delete、update三種觸發器。
下面來看一下執行個體:
這是我建立的資料庫兩張表:(T_card和T_type,並且兩張表設定了主鍵和外鍵約束)
下面是我執行刪除‘臨時使用者’所執行的結果。(這是因為外鍵約束造成的錯誤)
之後我再建立delete觸發器,看一下是否可以實現目的。
CREATE TRIGGER delType ON T_type AFTER deleteAS BEGINdeclare @typeId intdelete T_card where typeid in (select typeid from deleted) --從已經刪除的表中 取出typeIdENDGO
執行結果與上述錯誤相同。
在來看一下sql server中建立觸發器的定義模版:
大家注意到alter了沒有,insert delete update這三種觸發器都是在完成操作之後再執行之後的一系列sql語句。如果這觸發器的條件執行出錯,那麼後面的操作就都沒有辦法執行了。
因此,大家正在想。如果我先刪除‘臨時使用者’的卡號,在來刪除卡號類別,這樣錯誤不就沒有了嗎。
要找一系列操作來替代delete方法。
alter TRIGGER delType ON T_type instead of deleteAS BEGINdeclare @typeId intselect @typeId=typeid from deleted --從打算刪除的表中 取出typeId :還沒有刪除delete T_card where typeid in (select typeid from deleted) --先刪除卡類別對應的卡號delete T_type where <a target=_blank href="mailto:typeid=@typeid">typeid=@typeid</a>--在刪除卡號類別ENDGO
之後再執行sql語句看效果:
達到了想要的效果。在刪除了臨時使用者這個類別和臨時使用者的卡號。
可以使用觸發器的需求:當對某張表進行增刪改等操作的時候,需要對其他表進行一系列的操作。
使用觸發器,可以保證資料庫的完整性。預存程序和觸發器的編寫。可以減少程式的代碼,降低難度。同時也是為了減少重複代碼。對於一個系統來說,如果沒有使用觸發器和預存程序等方法。那麼代碼的編寫,重複量將是很可怕的。相反,如果設計好資料庫,寫好預存程序和觸發器等。在來看這個系統,那真是簡單多了。