觸發器是一種特殊的存儲過程﹐它不能被顯式地調用﹐而是在往表中插入記錄﹑更新記錄或者删除記錄時被自動地激活。是以觸發器可以用來實作對表實施複雜的完整性限制。
觸發器在資料庫裡以獨立的對象存儲,與存儲過程不同的是,存儲過程通過其他程式來啟動運作,而觸發器是由一個事件來啟動運作。即當某個事件發生時,觸發器自動地隐式運作。并且,觸發器不能接收參數。
觸發器對象定義了觸發器的特征和被調用時采取的行動。而這些動作是通過一個或多個sql語句來實作的。sql支援3種類型的觸發器:insert(插入)、update(更新)和delete(删除)。當向表中插入資料、更新資料或删除資料時,觸發器就被調用。通過給表定義一個或多個觸發器,可以指定哪個資料修改時,可以激發觸發器。
一、sql server
sql server為每個觸發器都建立了兩個專用表:inserted表和deleted表。這兩個表由系統來維護﹐它們存在于記憶體中而不是在資料庫中。這兩個表的結構總是與被該觸發器作用的表的結構相同。 觸發器執行完成後﹐與該觸發器相關的這兩個表也被删除。
deleted表存放由于執行delete或update語句而要從表中删除的所有行。
inserted表存放由于執行insert或update語句而要向表中插入的所有行。
在sqlserver中,可以采用createtrigger指令建立觸發器。文法如下:
trigger_name:為使用者要建立的觸發器的名字,觸發器的名字必須符合sqlserver的命名規則,且其名字在目前資料庫中必須是惟一的。
table、view:與觸發器相關聯的表或視圖的名字,并且該表或視圖必須已經在資料庫中存在。
withencryption:表示對含有createtrigger文本的syscomments表進行加密,防止使用者通過查詢syscomments表擷取觸發器的代碼。
after:表示隻有執行了指定的操作(insert、delete、或update)之後,觸發器才被激活,執行觸發器中的sql語句。
for:表示為after觸發器,且該觸發器僅能在表上建立。
insteadof:指定觸發器為insteadof觸發器
小注:每個表最多隻能有一個insteadof(insert、update、delete)觸發器。然而可以為每個表建立多個視圖,對每個視圖都可以有不同的insteadof觸發器。
delete、insert、update:指明執行哪種操作,将激活觸發器。至少要包含3種操作類型種的一種,也可以是3種操作語句的任意組合。其中三者的順序不受限制,且各選項要用逗号隔開。
notforreplication:告訴dbms,當複制表時,觸發器不能被執行。as:後面列出觸發器将要執行的動作。
ifupdatecolumn:用來測定對某一确定列是insert操作還是update操作。如果要測試insert還是update操作的列多于一列,可用and或or邏輯連接配接向ifupdate子句添加所希望的附加列名。
ifcolumns_updated():僅在insert和update類型的觸發器中使用,檢查列是被更新還是被插入。
bitwise_operator:代表位邏輯運算符,常用“&”。
updated_bitmask:表示列的整位掩碼。其中最右邊的位表示表或視圖的第1列,左邊第2位代表第2列,依此類推。
comparison_operator:表示比較操作符。可以是“=”或者“>”。“=”表示檢查在updated_bitmask中定義的所有列是否都被更新,用“>”表示檢查是否在updated_bitmask小注:
為了便于了解,這裡給出一個使用ifcolumns_updated()子句的例子。如果表t包括c1、c2、c3、c4、c5和c66列,為了檢查c2、c4或者c6列是否更新過,可使用42(二進制表示為“101010”)作為掩碼,表示為:if(columns_updated()&42)>0;如果檢查c2、c4和c63列是否都被更新過,表示為:if(columns_updated()&42)=42
sql_statement:代表包含在觸發器中的處理語句。
當不再需要觸發器時,可用droptrigger語句删除觸發器。文法如下:
二、oracle
在oracle中共有3種類型的觸發器:dml觸發器、替代觸發器和系統觸發器。
dml觸發器:oracle可以在dml語句(insert、update、delete)進行觸發,可以在dml操作前或操作後進行觸發,并且可以對每個行或語句上進行觸發。替代觸發器(insteadof):與sqlserver中的insteadof觸發器類似,由于在oracle裡,不能直接對由兩個以上的表建立的視圖進行操作。是以給出了替代觸發器。系統觸發器:從oracle8i開始,提供了第三種類型的觸發器叫系統觸發器。它可以在oracle的事件中進行觸發,如oracle系統的啟動與關閉等。
在oracle中,觸發器的建立也是通過createtrigger語句來實作的,但與sqlserver中的觸發器建立文法有較大的差别。文法如下:
說明如下:
rigger_name:為觸發器的名字。在oracle中,觸發器名與存儲過程名字不一樣,它是單獨的名字空間,因而觸發器名可以和表或存儲過程有相同的名字。
before|after:指明了觸發器是在資料修改前(before),還是修改後(after)被調用。
trigger_event:為觸發器事件,可以是insert、update或delete。如果要建立替代觸發器,則隻需在觸發事件前加上關鍵詞insteadof即可。
on:子句則包含了目标表的名稱,也就是觸發器應用的表。
foreachrow:指明每次插入、更新或删除一行時就調用觸發器。
when:是可選的,可以定義搜尋條件,來限制調用觸發器時的搜尋範圍。
trigger_body:為觸發器執行的sql語句,這些語句必須被放在begin……end塊中。
另外,在oracle中,觸發器的應用受到一定的限制,主要的限制條件有以下幾個。觸發器中可以包括dml語句,但不能使用控制語句、commit語句、rollback語句、svaepoint語句。然而,對于“系統觸發器”,則可以使用create語句、alter語句或者drop語句。由觸發器所調用的存儲過程或函數也不能使用控制語句。觸發器中不能使用long、longraw資料類型。