觸發(fā)器是一種特殊類(lèi)型的存儲(chǔ)過(guò)程,它在指定的表中的數(shù)據(jù)發(fā)生變化時(shí)自動(dòng)生效。喚醒調(diào)用觸發(fā)器以響應(yīng) INSERT、UPDATE 或 DELETE 語(yǔ)句。觸發(fā)器可以查詢(xún)其它表,并可以包含復(fù)雜的Transact-SQL語(yǔ)句。將觸發(fā)器和觸發(fā)它的語(yǔ)句作為可在觸發(fā)器內(nèi)回滾的單個(gè)事務(wù)對(duì)待。如果檢測(cè)到嚴(yán)重錯(cuò)誤(例如,磁盤(pán)空間不足),則整個(gè)事務(wù)即自動(dòng)回滾。
觸發(fā)器可通過(guò)數(shù)據(jù)庫(kù)中的相關(guān)表實(shí)現(xiàn)級(jí)聯(lián)更改;通過(guò)級(jí)聯(lián)引用完整性約束可以更有效地執(zhí)行這些更改。
觸發(fā)器可以強(qiáng)制用比 CHECK 約束定義的約束更為復(fù)雜的約束。
與 CHECK 約束不同,觸發(fā)器可以引用其它表中的列。例如,觸發(fā)器可以使用另一個(gè)表中的 SELECT 比較插入或更新的數(shù)據(jù),以及執(zhí)行其它操作,如修改數(shù)據(jù)或顯示用戶(hù)定義錯(cuò)誤信息。
觸發(fā)器也可以評(píng)估數(shù)據(jù)修改前后的表狀態(tài),并根據(jù)其差異采取對(duì)策。
比較觸發(fā)器與約束
約束和觸發(fā)器在特殊情況下各有優(yōu)勢(shì)。觸發(fā)器的主要好處在于它們可以包含使用 Transact-SQL 代碼的復(fù)雜處理邏輯。因此,觸發(fā)器可以支持約束的所有功能;但它在所給出的功能上并不總是最好的方法。
實(shí)體完整性總應(yīng)在最低級(jí)別上通過(guò)索引進(jìn)行強(qiáng)制,這些索引或是 PRIMARY KEY 和 UNIQUE 約束的一部分,或是在約束之外獨(dú)立創(chuàng)建的。假設(shè)功能可以滿(mǎn)足應(yīng)用程序的功能需求,域完整性應(yīng)通過(guò) CHECK 約束進(jìn)行強(qiáng)制,而引用完整性 (RI) 則應(yīng)通過(guò) FOREIGN KEY 約束進(jìn)行強(qiáng)制。
在約束所支持的功能無(wú)法滿(mǎn)足應(yīng)用程序的功能要求時(shí),觸發(fā)器就極為有用。例如:
除非 REFERENCES 子句定義了級(jí)聯(lián)引用操作,否則 FOREIGN KEY 約束只能以與另一列中的值完全匹配的值來(lái)驗(yàn)證列值。
CHECK 約束只能根據(jù)邏輯表達(dá)式或同一表中的另一列來(lái)驗(yàn)證列值。如果應(yīng)用程序要求根據(jù)另一個(gè)表中的列驗(yàn)證列值,則必須使用觸發(fā)器。
約束只能通過(guò)標(biāo)準(zhǔn)的系統(tǒng)錯(cuò)誤信息傳遞錯(cuò)誤信息。如果應(yīng)用程序要求使用(或能從中獲益)自定義信息和較為復(fù)雜的錯(cuò)誤處理,則必須使用觸發(fā)器。
觸發(fā)器可通過(guò)數(shù)據(jù)庫(kù)中的相關(guān)表實(shí)現(xiàn)級(jí)聯(lián)更改;不過(guò),通過(guò)級(jí)聯(lián)引用完整性約束可以更有效地執(zhí)行這些更改。
觸發(fā)器可以禁止或回滾違反引用完整性的更改,從而取消所嘗試的數(shù)據(jù)修改。當(dāng)更改外鍵且新值與主鍵不匹配時(shí),此類(lèi)觸發(fā)器就可能發(fā)生作用。例如,可以在 titleauthor.title_id 上創(chuàng)建一個(gè)插入觸發(fā)器,使它在新值與 titles.title_id 中的某個(gè)值不匹配時(shí)回滾一個(gè)插入。不過(guò),通常使用 FOREIGN KEY 來(lái)達(dá)到這個(gè)目的。
如果觸發(fā)器表上存在約束,則在 INSTEAD OF觸發(fā)器執(zhí)行后但在 AFTER觸發(fā)器執(zhí)行前檢查這些約束。如果約束破壞,則回滾INSTEAD OF觸發(fā)器操作并且不執(zhí)行 AFTER觸發(fā)器。
?
SQL 觸發(fā)器的作用,優(yōu)缺點(diǎn)
觸發(fā)器,主要是用來(lái)同步更新數(shù)據(jù)的,舉個(gè)例子吧:
假設(shè)有兩個(gè)表,tab_1 , tab_2
再假設(shè)兩個(gè)表里都有“人員性別”這個(gè)字段
tab_1的數(shù)據(jù)例如: 張三```男```1978`````2002
tab_2的數(shù)據(jù)例如: 張三```男```銷(xiāo)售科```科長(zhǎng)
我要改tab_1中張三的性別為“女”的話,那么tab_2的性別也該改為“女”,對(duì)吧,總不能兩張表的性別不同吧。
如果不用觸發(fā)器的話,我們就要改完tab_1,再去改tab_2,使性別都變成女
于是這里可以用到觸發(fā)器了:
原理是:當(dāng)tab_1中某人的性別發(fā)生變更后,數(shù)據(jù)庫(kù)自動(dòng)將tab_2的性別進(jìn)行同步修改
觸發(fā)器也可以這樣應(yīng)用:
1、當(dāng)刪除tab_1中的某人信息時(shí),觸發(fā)器一并刪除該人的tab_2中的數(shù)據(jù)
2、在tab_1中新插入一個(gè)人員時(shí),觸發(fā)器在tab_2中一并新增一條該人的數(shù)據(jù)
===================================================================================
所以在你建立觸發(fā)器時(shí),就要指定該觸發(fā)器的用途,是同步更新,還是刪除、插入,由你指定。
基本的語(yǔ)法規(guī)則是:
create trigger 觸發(fā)器名稱(chēng)(你自己命名的) on 表 for 用途(delete|update|insert)
as
delete|update|insert語(yǔ)句
----------------------------------------------------------------------
例如:
create trigger tri_A on tab_1 FOR DELETE
AS
delete tab_2 from deleted where tab_2.id = deleted.id;
意思是:在tab_1表上,建立觸發(fā)器(tri_A),用于刪除該表的數(shù)據(jù)時(shí)觸發(fā)一個(gè)事務(wù),什么事務(wù)呢?——?jiǎng)h除tab_2中的該編號(hào)人員的記錄。
FOR INSERT、FOR UPDATE分別是建立用于“插入記錄”、“更新數(shù)據(jù)”的觸發(fā)器,例子里的FOR DELETE是用于觸發(fā)“刪除記錄”的。
這里還要看清楚,那個(gè)delete語(yǔ)句中的表,是from deleted哦,還有,where子句的tab_2.id = deleted.id,不是tab_2.id = tab_1.id哦,deleted.id是指你剛刪除的那條記錄的id(而update、insert,都用inserted.id)
===================================================================================
好處:相對(duì)于外部程序、存儲(chǔ)過(guò)程,觸發(fā)器可以更快更高效的維護(hù)數(shù)據(jù)
壞處:(我自己的經(jīng)驗(yàn))觸發(fā)器要用的恰到好處,一個(gè)大型應(yīng)用里,觸發(fā)器越少越好,觸發(fā)器會(huì)使編程時(shí)源碼的結(jié)構(gòu)被迫打亂,為將來(lái)的程序修改、源碼閱讀帶來(lái)很大不便
電子發(fā)燒友App




















































評(píng)論