文章目錄
--淺析觸發器
1、關於inserted 表和deleted 表
觸發器語句中使用了兩種特殊的表:inserted 表和deleted 表
inserted 表放的是本次insert操作插入的資料或本次update操作更新後的資料。
deleted 表放的是本次delete操作刪除的資料或本次update操作更新前的資料。
2、inserted 表和deleted 表裡的記錄數。
該記錄數取決於是批量插入還是單條插入。
如:
insert tb select 1 union select 2 union select 3 union select 4
--以上就屬於批量插入,只觸發一次insert觸發器,但是inserted裡面同時有4條資料。
insert tb select 1
insert tb select 2
insert tb select 3
insert tb select 4
--以上屬於單條插入,每插入一條觸發一次insert觸發器,每次觸發器裡只有一條資料。
3、這個也很重要
將觸發器裡的語句和觸發它的語句作為可在觸發器內復原的單個事務對待。
也就是說,向表插入資料成功了,但是觸發器的操作報錯了,那麼整個事務是復原的,即
本表資料插入復原,觸發器裡的語句操作復原。
如果在觸發器裡復原觸發器裡的SQL,且不影響原有的操作,建議用
set xact_abort off 選項。
4、關於 for 觸發器和 instead of 觸發器。
for 等同於 after,也就是在insert、delete或update之後,才執行觸發器裡的語句。
instead of 等同於代替insert、delete或update操作。雖然,這時候inserted或deleted兩個特殊
表裡有資料,但是並沒有對本表資料進行insert、delete或update操作,這樣的話,你還要在觸發
器裏手工進行對本表insert、delete或update的操作。
5、if update(colname)
大家注意哦,這個不只會在update觸發器裡用到,INSERT觸發器裡也會用到的。以下是說明:
對特定列的更改進行測試
觸發器定義中的 IF UPDATE (列名)子句可用來確定 INSERT 或 UPDATE 語句是否影響到表中的一個特定列。
無論何時,當列被賦值時,該子句即為 TRUE。
還有:
IF COLUMNS_UPDATED() 子句檢查表中已用 INSERT 或 UPDATE 語句更新的列。該子句使用整型位元遮罩指定需測試的列
http://blog.csdn.net/sdhdy/archive/2009/06/07/4249668.aspx
簡介 觸發器可以查詢其他表,而且可以包含複雜的 SQL 陳述式。它們主要用於強制服從複雜的商務規則或要求。例如:您可以根據客戶當前的帳戶狀態,控制是否允許插入新訂單。
觸發器也可用於強制參考完整性,以便在多個表中添加、更新或刪除行時,保留在這些表之間所定義的關係。然而,強制參考完整性的最好方法是在相關表中定義主鍵和外鍵約束。如果使用資料庫圖表,則可以在表之間建立關係以自動建立外鍵約束。建立觸發器的SQL文法 DELIMITER |
CREATE TRIGGER `<databaseName>`.`<triggerName>`
< [ BEFORE | AFTER ] > < [ INSERT | UPDATE | DELETE ] >
ON <tableName>
FOR EACH ROW
BEGIN
--do something
END |觸發器的優點
觸發器可通過資料庫中的相關表實現級聯更改;不過,通過級聯參考完整性約束可以更有效地執行這些更改。觸發器可以強制比用 CHECK
約束定義的約束更為複雜的約束。與 CHECK 條件約束不同,觸發器可以引用其它表中的列。例如,觸發器可以使用另一個表中的 SELECT
比較插入或更新的資料,以及執行其它操作,如修改資料或顯示使用者定義錯誤資訊。觸發器也可以評估資料修改前後的表狀態,並根據其差異採取對策。一個表中的
多個同類觸發器(INSERT、UPDATE 或 DELETE)允許採取多個不同的對策以響應同一個修改語句。比較觸發器與約束
約束和觸發器在特殊情況下各有優勢。觸發器的主要好處在於它們可以包含使用 Transact-SQL
代碼的複雜處理邏輯。因此,觸發器可以支援約束的所有功能;但它在所給出的功能上並不總是最好的方法。實體完整性總應在最低層級上通過索引進行強制,這些
索引或是 PRIMARY KEY 和 UNIQUE 約束的一部分,或是在約束之外獨立建立的。假設功能可以滿足應用程式的功能需求,值域完整性應通過
CHECK 條件約束進行強制,而參考完整性 (RI) 則應通過 FOREIGN KEY
約束進行強制。在約束所支援的功能無法滿足應用程式的功能要求時,觸發器就極為有用。
例如:除非 REFERENCES 子句定義了級聯引用操作,否則 FOREIGN KEY 約束只能以與另一列中的值完全符合的值來驗證列值。
CHECK 條件約束只能根據邏輯運算式或同一表中的另一列來驗證列值。如果應用程式要求根據另一個表中的列驗證列值,則必須使用觸發器。
約束只能通過標準的系統錯誤資訊傳遞錯誤資訊。如果應用程式要求使用(或能從中獲益)自訂資訊和較為複雜的錯誤處理,則必須使用觸發器。
觸發器可通過資料庫中的相關表實現級聯更改;不過,通過級聯參考完整性約束可以更有效地執行這些更改。
觸發器可以禁止或復原違反參考完整性的更改,從而取消所嘗試的資料修改。當更改外鍵且新值與主
鍵不匹配時,此類觸發器就可能發生作用。例如,可以在 titleauthor.title_id 上建立一個插入觸發器,使它在新值與
titles.title_id 中的某個值不匹配時復原一個插入。不過,通常使用 FOREIGN KEY 來達到這個目的。
如果觸發器表上存在約束,則在 INSTEAD OF 觸發器執行後但在 AFTER 觸發器執行前檢查這些約束。如果約束破壞,則復原 INSTEAD OF 觸發器操作並且不執行 AFTER 觸發器。
觸發器到底可不可以在視圖上建立 在 SQL Server 聯機叢書中,是沒有說觸發器不能在視圖上建立的, 並且在文法解釋中表明:
在 CREATE TRIGGER 的 ON 之後可以是視圖。
然而,事實似乎並不是如此,很多專家也說觸發器不能在視圖上建立。我也專門作了測試,的確如此,不管是普通視圖還是索引檢視表,都無法在上面建立觸發器,真
的是這樣嗎?請點擊詳細,但是無可厚非的是:當在暫存資料表或系統資料表上建立觸發器時會遭到拒絕。 深刻理解 FOR CREATE TRIGGER 語句的
FOR 關鍵字之後可以跟 INSERT、UPDATE、DELETE 中的一個或多個,也就是說在其它情況下是不會觸發觸發器的, 包括
SELECT、TRUNCATE、WRITETEXT、UPDATETEXT。相關內容
一個有趣的應用我們看到許多註冊系統在註冊後都不能更改使用者名稱,但這多半是由應用程式決定的, 如果直接開啟資料庫表變更,同樣可以更改其使用者名稱,
在觸發器中利用復原就可以巧妙地實現無法更改使用者名稱……詳細內容 觸發器內部語句出錯時……
這種情況下,前面對資料更改操作將會無效。舉個例子,在表中插入資料時觸發觸發器,而觸發器內部此時發生了執行階段錯誤,那麼將返回一個錯誤值,並且拒絕剛
才的資料插入。不能在觸發器中使用的語句 觸發器中可以使用大多數 T-SQL 陳述式,但如下一些語句是不能在觸發器中使用的。
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的觸發器中不可使用!慎用觸發器 觸發器功能強大,輕鬆可靠地實現許多複雜的功能,為什麼又要慎用呢。觸發器本身沒有過錯,但由於我們的濫用會造成資料庫及應用程式的維護困難。在資料庫操作中,我們可以通過關係、觸發器、預存程序、應用程式等來實現資料操作…… 同時規則、約束、預設值也是保證資料完整性的重要保障。如果我們對觸發器過分的依賴,勢必影響資料庫的結構,同時增加了維護的複雜程式.
sqlserver觸發器
http://blog.csdn.net/lavly/archive/2009/07/18/4356275.aspx
一﹕ 觸發器是一種特殊的預存程序﹐它不能被顯式地調用﹐而是在往表中插入記錄﹑更新記錄或者刪除記錄時被自動地啟用。所以觸發器可以用來實現對錶實施複雜的完整性約`束。
二﹕ SQL Server為每個觸發器都建立了兩個專用表﹕Inserted表和Deleted表。這兩個表由系統來維護﹐它們存在於記憶體中而不是在資料庫中。這兩個表的結構總是與被該觸發器作用的表的結構相同。觸發器執行 完成後﹐與該觸發器相關的這兩個表也被刪除。
Deleted表存放由於執行Delete或Update語句而要從表中刪除的所有行。
Inserted表存放由於執行Insert或Update語句而要向表中插入的所有行。
三﹕Instead of 和 After觸發器
SQL Server2000提供了兩種觸發器﹕Instead of 和After 觸發器。這兩種觸發器的差別在於他們被啟用的同﹕
Instead of觸發器用於替代引起觸發器執行的T-SQL語句。除表之外﹐Instead of 觸發器也可以用於視圖﹐用來擴充視圖可以支援的更新操作。
After觸發器在一個Insert,Update或Deleted語句之後執行﹐進行約束檢查等動作都在After觸發器被啟用之前發生。After觸發器只能用於表。
一個表或視圖的每一個修改動作(insert,update和delete)都可以有一個instead of 觸發器﹐一個表的每個修改動作都可以有多個After觸發器。
四﹕觸發器的執行過程
如果一個Insert﹑update或者delete語句違反了約束﹐那么After觸發器不會執行﹐因為對約束的檢查是在After觸發器被激動之前發生的。所以After觸發器不能超越約束。
Instead of 觸發器可以取代激發它的操作來執行。它在Inserted表和Deleted表剛剛建立﹐其它任何操作還沒有發生時被執行。因為Instead of 觸發器在約束之前執行﹐所以它可以對約束進行一些預先處理。
五﹕使用T-SQL語句來建立觸發器
基本語句如下﹕
create trigger trigger_name
on {table_name | view_name}
{for | After | Instead of }
[ insert, update,delete ]
as
sql_statement
六﹕相關樣本﹕
1﹕在Orders表中建立觸發器﹐當向Orders表中插入一條訂單記錄時﹐檢查goods表的貨品狀態status是否為1(正在整理)﹐是﹐則不能往Orders表加入該訂單。
create trigger orderinsert
on orders
after insert
as
begin transaction
if (select status from goods,inserted
where goods.name=inserted.goodsname)=1
begin
print 'the goods is being processed'
print 'the order cannot be committed'
rollback transaction --復原﹐避免加入
end
2﹕在Orders表建立一個插入觸發器﹐在添加一條訂單時﹐減少Goods表相應的貨品記錄中的庫存。
create trigger orderinsert1
on orders
after insert
as
begin transaction
update goods set storage=storage-inserted.quantity
from goods,inserted
where
goods.name=inserted.goodsname
3﹕在Goods表建立刪除觸發器﹐實現Goods表和Orders表的串聯刪除。
create trigger goodsdelete
on goods
after delete
as
begin transaction
delete from orders
where goodsname in
(select name from deleted)
4﹕在Orders表建立一個更新觸發器﹐監視Orders表的訂單日期(OrderDate)列﹐使其不能手工修改.
create trigger orderdateupdate
on orders
after update
as
begin transaction
if update(orderdate)
begin
raiserror(' orderdate cannot be modified',10,1)
rollback transaction
end
5﹕在Orders表建立一個插入觸發器﹐保證向Orders表插入的貨品名必須要在Goods表中一定存在。
create trigger orderinsert3
on orders
after insert
as
begin transaction
if (select count(*) from goods,inserted where goods.name=inserted.goodsname)=0
begin
print ' no entry in goods for this order'
rollback transaction
end
觸發器的基礎知識和例子
:create trigger tr_name
on table/view
{for | after | instead of } [update][,][insert][,][delete]
[with encryption]
as {batch | if update (col_name) [{and|or} update (col_name)] }
說明:1 tr_name :觸發器名稱
2 on table/view :觸發器所作用的表。一個觸發器只能作用於一個表
3 for 和after :同義
4 after 與instead of :sql 2000新增項目
after 與 instead of 的區別
After Instead of
在觸發事件發生以後才被啟用 代替了相應的觸發事件而被執行
只可以建立在表上 既可以建立在表上也可以建立在視圖上
5 insert、update、delete:啟用觸發器的三種操作,可以同時執行,也可選其一
6 if update (col_name):表明所作的操作對指定列是否有影響,有影響,則啟用觸發器。此外,因為delete 操作只對行有影響,所以如果使用delete
操作就不能用這條語句了(雖然使用也不出錯,但是不能啟用觸發器,沒意義)。
7 觸發器執行時用到的兩個特殊表:deleted ,inserted
deleted 和inserted 可以說是一種特殊的暫存資料表,是在進行啟用觸發器時由系統自動產生的,其結構與觸發器作用的表結構是一樣的,只是存放 的資料有差異。
續
下面表格說明deleted 與inserted 資料的差異
deleted 與inserted 資料的差異
Inserted | Deleted
存放進行insert和update 操作後的資料 |存放進行delete 和update操作前的
資料
注意:update 操作相當於先進行delete 再進行insert ,所以在進行update操作時,修改前的資料拷貝一條到deleted 表中,修改後的資料在存到觸發器作用的表的同時,也同時產生一條拷貝到insered表中
use pubs
go
BEGIN TRAN
create table table1(列1 int,列2 int)
create table table2(列11 int,列22 int)
go
CREATE TRIGGER t_dalii ON table1
AFTER INSERT
----^^^^^^當插入時觸發
AS
begin
SELECT * FROM TABLE2;
insert table2 select * from inserted
-------------------------------^^^^^^^^^存放插入臨時資料的暫存資料表
end
go
----------**你向table1插入資料時table2也會插入同樣的資料**--
insert table1 values(1,2)
select * from table1
select * from table2
drop table table1
drop table table2
COMMIT TRAN