建立觸發(fā)器的SQL語(yǔ)句
回顧一下,在Management Studio新建一個(gè)觸發(fā)器的時(shí)候,它在查詢(xún)分析對話(huà)框給預設了一些SQL代碼,這些代碼其實(shí)上就是建立觸發(fā)器的語(yǔ)法提示?,F在來(lái)看一下完整的觸發(fā)器語(yǔ)法代碼:
CREATE TRIGGER <Schema_Name, sysname, Schema_Name>.<Trigger_Name, sysname, Trigger_Name>
ON <Schema_Name, sysname, Schema_Name>.<Table_Name, sysname, Table_Name>
AFTER <Data_Modification_Statements, , INSERT,DELETE,UPDATE>
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
END
GO
用中文改了一下,以上代碼就一目了然了:
CREATE TRIGGER 觸發(fā)器名
ON 數據表名或視圖名
AFTER INSERT或DELETE或UPDATE
AS
BEGIN
--這里是要運行的SQL語(yǔ)句
END
GO
現在再對上面的代碼進(jìn)行進(jìn)一步的說(shuō)明:
l CREATE TRIGGER 觸發(fā)器名:這一句聲明SQL語(yǔ)句是用來(lái)建立一個(gè)觸發(fā)器。其中觸發(fā)器名在所在的數據庫里必須是唯一的。由于觸發(fā)器是建立中數據表或視圖中的,所以有很多人都以為只要是在不同的數據表中,觸發(fā)器的名稱(chēng)就可以相同,其實(shí)觸發(fā)器的全名(Server.Database.Owner.TriggerName)是必須唯一的,這與觸發(fā)器在哪個(gè)數據表或視圖無(wú)關(guān)。
l ON 數據表名或視圖名:這是指定觸發(fā)器所在的數據表或視圖,但是請注意,只有Instead Of觸發(fā)器才能建立在視圖上。并且,有設置為With Check Option的視圖也不允許建立Instead Of觸發(fā)器。
l AFTER INSERT或 DELETE UPDATE:這是指定觸發(fā)器的類(lèi)型,是After Insert觸發(fā)器,還是After Delete觸發(fā)器,或者是After Update觸發(fā)器。其中After可以用For來(lái)代取,它們的意思都是一樣的,代表只有在數據表的操作都已正確完成后才會(huì )激活的觸發(fā)器。INSERT、DELETE和UPDATE至少要指定一個(gè),當然也可以指定多個(gè),若指定多個(gè)時(shí),必須用逗號來(lái)分開(kāi)。其順序可以任意擺放。
l With Encryption:With Encryption是用來(lái)加密觸發(fā)器的,放在“On 數據表名或視圖名”的后面,“For”的前面。如果使用了這句話(huà),該觸發(fā)器將會(huì )被加密,任何人都看不到觸發(fā)器的內容了。
例一:以下是一個(gè)包含提醒電子郵件的觸發(fā)器例子,如果訂單表里記錄有改動(dòng)的的話(huà)(無(wú)論增加訂單還是修改、刪除訂單),則給物流人員張三發(fā)送電子郵件:
CREATE TRIGGER 訂單_Insert
ON 訂單
AFTER INSERT, UPDATE, DELETE
AS
EXEC master..xp_sendmail '張三',
'訂單有更改,請查詢(xún)確定'
GO
例二:在訂單明細表里,折扣字段不能大于0.6,如果插入記錄時(shí),折扣大于0.6的話(huà),回滾操作。
CREATE TRIGGER 訂單明細_Insert
ON 訂單明細
AFTER INSERT
AS
BEGIN
if (Select 折扣 from inserted)>0.6
begin
print '折扣不能大于0.6'
Rollback Transaction
end
END
GO
在示例二中運用了兩個(gè)方法,一個(gè)是前面說(shuō)過(guò)的,在Inserted表里查詢(xún)某個(gè)字段,還有一個(gè)是用Rollback Transaction來(lái)回滾操作。如果用下面的SQL語(yǔ)句來(lái)進(jìn)行Insert操作的話(huà),插入記錄將會(huì )不成功。
INSERT INTO 訂單明細(訂單ID,產(chǎn)品ID,單價(jià),數量,折扣)
VALUES (11077,1,18,1,0.7)
運行結果如圖7所示:
圖7 插入記錄不符合觸發(fā)器里的約束,則回滾操作
設置After觸發(fā)器的激活順序
對于同一個(gè)操作,如Insert、Update或Delete來(lái)說(shuō),可以建立多個(gè)After Insert觸發(fā)器,在
CREATE TRIGGER 產(chǎn)品_Insert1
ON 產(chǎn)品
AFTER INSERT
AS
BEGIN
print '再一次告訴你,你又添加了一種產(chǎn)品'
END
GO
重新運行一下插入產(chǎn)品的SQL語(yǔ)句:
INSERT INTO 產(chǎn)品(產(chǎn)品名稱(chēng))
VALUES ('大蘋(píng)果')
如圖8所示,運行一個(gè)Insert語(yǔ)句,在【消息】可以看到一共輸出了兩句話(huà),說(shuō)明激活兩個(gè)不同的觸發(fā)器。
圖8 一個(gè)語(yǔ)句激活兩個(gè)觸發(fā)器
當同一個(gè)操作定義的觸發(fā)器越來(lái)越多的時(shí)候,觸發(fā)器被激活的次序就會(huì )變得越來(lái)越重要了。在SQL Server 2005里,用存儲過(guò)程【sp_settriggerorder】可以為每一個(gè)操作各指定一個(gè)最先執行的After觸發(fā)器和最后執行的After觸發(fā)器。sp_settriggerorder語(yǔ)法如下:
sp_settriggerorder [ @triggername = ] '[ triggerschema. ] triggername'
, [ @order = ] 'value'
, [ @stmttype = ] 'statement_type'
[ , [ @namespace = ] { 'DATABASE' | 'SERVER' | NULL } ]
翻譯成中文就是
sp_settriggerorder 觸發(fā)器名,
激活次序,
激活觸發(fā)器的動(dòng)作
解釋如下:
l 觸發(fā)器名,要用單引號括起來(lái),因為它是一個(gè)字符串。
l 激活次序可以為First、Last和None:First是指第一個(gè)要激活的觸發(fā)器;Last是指它最后一個(gè)要激活的觸發(fā)器;None是不指激活序,由程序任意觸發(fā)。
l 激活觸發(fā)器的動(dòng)作可以是:Insert、Update和Delete。
上面的例子里,先激活的是【產(chǎn)品_Insert】觸發(fā)器,后激活的是【產(chǎn)品_Insert1】觸發(fā)器。如果把【產(chǎn)品_Insert1】觸發(fā)器設為First觸發(fā)器,把【產(chǎn)品_Insert】觸發(fā)器設為Last觸發(fā)器,那么結果將會(huì )完全不一樣。設置語(yǔ)句如下:
Exec sp_settriggerorder
'產(chǎn)品_Insert1','First','Insert'
go
Exec sp_settriggerorder
'產(chǎn)品_Insert',’Last’,'Insert'
Go
重新運行一下插入產(chǎn)品的SQL語(yǔ)句:
INSERT INTO 產(chǎn)品(產(chǎn)品名稱(chēng))
VALUES ('大蘋(píng)果')
運行結果如圖9,與圖8比較一下,是不是激活次序已經(jīng)發(fā)生變化了?
圖9 按次序激活的激活器
在設置After觸發(fā)器激活順序時(shí),還有幾點(diǎn)是需要注意的:
l 每個(gè)操作最多只能設一個(gè)First觸發(fā)器和一個(gè)Last觸發(fā)器。
l 如果要取消已經(jīng)設好的First觸發(fā)器或Last觸發(fā)器,只要把它們設為None觸發(fā)器即可。
l 如果用Alter命令修改過(guò)觸發(fā)器內容后,該觸發(fā)器會(huì )自動(dòng)變成None觸發(fā)器。所以用Alter命令也可以用來(lái)取消已經(jīng)設好的First觸發(fā)器或Last觸發(fā)器。
l 只有After觸發(fā)器可以設置激活次序,Instead Of觸發(fā)器不可以設置激活次序。
l 激活觸發(fā)器的動(dòng)作必須和觸發(fā)器內部的激活動(dòng)作一致。舉例說(shuō)明:After Insert觸發(fā)器,只能為Insert操作設置激活次序,不能為Delete操作設置激活次序。以下的設置是錯誤的:
Exec sp_settriggerorder
'產(chǎn)品_Insert1','First',’Update’
聯(lián)系客服