触发器的简单使用
觸發(fā)器的作用
[1]??觸發(fā)器有如下作用:- 可在寫入數(shù)據(jù)表前,強(qiáng)制檢驗(yàn)或轉(zhuǎn)換數(shù)據(jù)。
- 觸發(fā)器發(fā)生錯(cuò)誤時(shí),異動的結(jié)果會被撤銷。
- 部份數(shù)據(jù)庫管理系統(tǒng)可以針對數(shù)據(jù)定義語言(DDL)使用觸發(fā)器,稱為DDL觸發(fā)器。
- 可依照特定的情況,替換異動的指令 (INSTEAD OF)。
SQL語法
DELIMITER | CREATE TRIGGER `<databaseName>`.`<triggerName>` < [ BEFORE | AFTER ] > < [ INSERT | UPDATE | DELETE ] > ON [dbo]<tableName> //dbo代表該表的所有者 FOR EACH ROW BEGIN --do something END |優(yōu)點(diǎn)
觸發(fā)器可通過數(shù)據(jù)庫中的相關(guān)表實(shí)現(xiàn)級聯(lián)更改,不過,通過級聯(lián)引用完整性約束可以更有效地執(zhí)行這些更改。觸發(fā)器可以強(qiáng)制用比CHECK約束定義的約束更為復(fù)雜的約束。與 CHECK 約束不同,觸發(fā)器可以引用其它表中的列。例如,觸發(fā)器可以使用另一個(gè)表中的 SELECT 比較插入或更新的數(shù)據(jù),以及執(zhí)行其它操作,如修改數(shù)據(jù)或顯示用戶定義錯(cuò)誤信息。觸發(fā)器也可以評估數(shù)據(jù)修改前后的表狀態(tài),并根據(jù)其差異采取對策。一個(gè)表中的多個(gè)同類觸發(fā)器(INSERT、UPDATE 或 DELETE)允許采取多個(gè)不同的對策以響應(yīng)同一個(gè)修改語句。觸發(fā)器和約束
約束和觸發(fā)器在特殊情況下各有優(yōu)勢。觸發(fā)器的主要好處在于它們可以包含使用 Transact-SQL 代碼的復(fù)雜處理邏輯。因此,觸發(fā)器可以支持約束的所有功能;但它在所給出的功能上并不總是最好的方法。實(shí)體完整性總應(yīng)在最低級別上通過索引進(jìn)行強(qiáng)制,這些索引或是 PRIMARY KEY 和 UNIQUE 約束的一部分,或是在約束之外獨(dú)立創(chuàng)建的。假設(shè)功能可以滿足應(yīng)用程序的功能需求,域完整性應(yīng)通過 CHECK 約束進(jìn)行強(qiáng)制,而引用完整性(RI) 則應(yīng)通過 FOREIGN KEY 約束進(jìn)行強(qiáng)制。在約束所支持的功能無法滿足應(yīng)用程序的功能要求時(shí),觸發(fā)器就極為有用。 例如:除非 REFERENCES 子句定義了級聯(lián)引用操作,否則 FOREIGN KEY 約束只能以與另一列中的值完全匹配的值來驗(yàn)證列值。 CHECK 約束只能根據(jù)邏輯表達(dá)式或同一表中的另一列來驗(yàn)證列值。如果應(yīng)用程序要求根據(jù)另一個(gè)表中的列驗(yàn)證列值,則必須使用觸發(fā)器。約束只能通過標(biāo)準(zhǔn)的系統(tǒng)錯(cuò)誤信息傳遞錯(cuò)誤信息。如果應(yīng)用程序要求使用(或能從中獲益)自定義信息和較為復(fù)雜的錯(cuò)誤處理,則必須使用觸發(fā)器。 觸發(fā)器可通過數(shù)據(jù)庫中的相關(guān)表實(shí)現(xiàn)級聯(lián)更改;不過,通過級聯(lián)引用完整性約束可以更有效地執(zhí)行這些更改。觸發(fā)器可以禁止或回滾違反引用完整性的更改,從而取消所嘗試的數(shù)據(jù)修改。當(dāng)更改外鍵且新值與主鍵不匹配時(shí),此類觸發(fā)器就可能發(fā)生作用。例如,可以在 titleauthor.title_id 上創(chuàng)建一個(gè)插入觸發(fā)器,使它在新值與 titles.title_id 中的某個(gè)值不匹配時(shí)回滾一個(gè)插入。不過,通常使用 FOREIGN KEY 來達(dá)到這個(gè)目的。 如果觸發(fā)器表上存在約束,則在 INSTEAD OF 觸發(fā)器執(zhí)行后但在 AFTER 觸發(fā)器執(zhí)行前檢查這些約束。如果約束破壞,則回滾 INSTEAD OF 觸發(fā)器操作并且不執(zhí)行 AFTER 觸發(fā)器。 觸發(fā)器到底可不可以在視圖上創(chuàng)建 在 SQL Server? 聯(lián)機(jī)叢書中,是沒有說觸發(fā)器不能在視圖上創(chuàng)建的, 并且在語法解釋中表明:在 CREATE TRIGGER 的 ON 之后可以是視圖。 然而,事實(shí)似乎并不是如此,很多專家也說觸發(fā)器不能在視圖上創(chuàng)建。我也專門作了測試,的確如此,不管是普通視圖還是索引視圖,都無法在上面創(chuàng)建觸發(fā)器,真的是這樣嗎? 但是無可厚非的是:當(dāng)在臨時(shí)表或系統(tǒng)表上創(chuàng)建觸發(fā)器時(shí)會遭到拒絕。 深刻理解 FOR CREATE TRIGGER 語句的 FOR 關(guān)鍵字之后可以跟 INSERT、UPDATE、DELETE 中的一個(gè)或多個(gè),也就是說在其它情況下是不會觸發(fā)觸發(fā)器的, 包括 SELECT、TRUNCATE、WRITETEXT、UPDATETEXT。 相關(guān)內(nèi)容 一個(gè)有趣的應(yīng)用我們看到許多注冊系統(tǒng)在注冊后都不能更改用戶名,但這多半是由應(yīng)用程序決定的, 如果直接打開數(shù)據(jù)庫表進(jìn)行更改,同樣可以更改其用戶名, 在觸發(fā)器中利用回滾就可以巧妙地實(shí)現(xiàn)無法更改用戶名……詳細(xì)內(nèi)容 觸發(fā)器內(nèi)部語句出錯(cuò)時(shí)…… 這種情況下,前面對數(shù)據(jù)更改操作將會無效。舉個(gè)例子,在表中插入數(shù)據(jù)時(shí)觸發(fā)觸發(fā)器,而觸發(fā)器內(nèi)部此時(shí)發(fā)生了運(yùn)行時(shí)錯(cuò)誤,那么將返回一個(gè)錯(cuò)誤值,并且拒絕剛才的數(shù)據(jù)插入。不能在觸發(fā)器中使用的語句 觸發(fā)器中可以使用大多數(shù) T-SQL 語句,但如下一些語句是不能在觸發(fā)器中使用的。 CREATE 語句,如:CREATE DATABASE、CREATE TABLE、CREATE INDEX 等。 ALTER 語句,如:ALTER DATABASE、ALTER TABLE、ALTER INDEX 等。 DROP 語句,如:DROP DATABASE、DROP TABLE、DROP INDEX 等。 DISK 語句,如:DISK INIT、DISK RESIZE。 LOAD 語句,如:LOAD DATABASE、LOAD LOG。 RESTORE 語句,如:RESTORE DATABASE、RESTORE LOG。 RECONFIGURE TRUNCATE TABLE 語句在sybase的觸發(fā)器中不可使用!慎用觸發(fā)器
觸發(fā)器功能強(qiáng)大,輕松可靠地實(shí)現(xiàn)許多復(fù)雜的功能,為什么又要慎用呢。觸發(fā)器本身沒有過錯(cuò),但由于我們的濫用會造成數(shù)據(jù)庫及應(yīng)用程序的維護(hù)困難。在數(shù)據(jù)庫操作中,我們可以通過關(guān)系、觸發(fā)器、存儲過程、應(yīng)用程序等來實(shí)現(xiàn)數(shù)據(jù)操作…… 同時(shí)規(guī)則、約束、缺省值也是保證數(shù)據(jù)完整性的重要保障。如果我們對觸發(fā)器過分的依賴,勢必影響數(shù)據(jù)庫的結(jié)構(gòu),同時(shí)增加了維護(hù)的復(fù)雜程度。Sqlserver示例
insert
1 create trigger tri_insert 2 on student 3 for insert 4 as 5 declare @student_idchar(10) 6 select @student_id=s.student_id from students 7 inner join insertedion s.student_id=i.student_id 8 if @student_id='0000000001' 9 begin 10 raiserror('不能插入1的學(xué)號!',16,8) 11 rollbacktran 12 end 13 goupdate
1 create trigger tri_update 2 on student 3 for update 4 as 5 if update(student_id) 6 begin 7 raiserror('學(xué)號不能修改!',16,8) 8 rollbacktran 9 end 10 go?
delete
1 create trigger tri_delete 2 on student 3 for delete 4 as 5 declare @student_idvarchar(10) 6 select @student_id=student_id from deleted 7 if @student_id='admin' 8 begin 9 raiserror('錯(cuò)誤',16,8) 10 rollbacktran?
轉(zhuǎn)載于:https://www.cnblogs.com/renzhitian/p/6086468.html
總結(jié)
- 上一篇: windows根据端口号找进程
- 下一篇: 简单工厂模式(1)