SQL触发器
一、觸發(fā)器是一種特殊的存儲(chǔ)過(guò)程,它不能被顯式地調(diào)用,而是在往表中插入記錄﹑更新記錄或者刪除記錄時(shí)被自動(dòng)地激活。所以觸發(fā)器可以用來(lái)實(shí)現(xiàn)對(duì)表實(shí)施復(fù)雜的完整性約束。
二、SQL Server為每個(gè)觸發(fā)器都創(chuàng)建了兩個(gè)專用表:Inserted表和Deleted表。
這兩個(gè)表由系統(tǒng)來(lái)維護(hù),它們存在于內(nèi)存中而不是在數(shù)據(jù)庫(kù)中。這兩個(gè)表的結(jié)構(gòu)總是與被該觸發(fā)器作用的表的結(jié)構(gòu)相同。觸發(fā)器執(zhí)行 完成后,與該觸發(fā)器相關(guān)的這兩個(gè)表也被刪除。
Deleted表存放由于執(zhí)行Delete或Update語(yǔ)句,而要從表中刪除的所有行。
Inserted表存放由于執(zhí)行Insert或Update語(yǔ)句,而要向表中插入的所有行。
三、Instead of 和 After觸發(fā)器
SQL Server2000提供了兩種觸發(fā)器:Instead of 和After 觸發(fā)器。這兩種觸發(fā)器的差別在于他們被激活的時(shí)間。
Instead of觸發(fā)器用于替代引起觸發(fā)器執(zhí)行的T-SQL語(yǔ)句。除表之外,Instead of 觸發(fā)器也可以用于視圖,用來(lái)擴(kuò)展視圖可以支持的更新操作。
After觸發(fā)器在一個(gè)Insert,Update或Deleted語(yǔ)句之后執(zhí)行,進(jìn)行約束檢查等動(dòng)作都在After觸發(fā)器被激活之前發(fā)生。After觸發(fā)器只能用于表。
一個(gè)表或視圖的每一個(gè)修改動(dòng)作(insert,update和delete)都可以有一個(gè)instead of 觸發(fā)器,一個(gè)表的每個(gè)修改動(dòng)作都可以有多個(gè)After觸發(fā)器。
四、觸發(fā)器的執(zhí)行過(guò)程
如果一個(gè)Insert﹑update或者delete語(yǔ)句違反了約束,那幺After觸發(fā)器不會(huì)執(zhí)行,因?yàn)閷?duì)約束的檢查是在After觸發(fā)器被激動(dòng)之前發(fā)生的。所以After觸發(fā)器不能超越約束。
Instead of 觸發(fā)器可以取代激發(fā)它的操作來(lái)執(zhí)行。它在Inserted表和Deleted表剛剛建立,其它任何操作還沒(méi)有發(fā)生時(shí)被執(zhí)行。因?yàn)镮nstead of 觸發(fā)器在約束之前執(zhí)行,所以它可以對(duì)約束進(jìn)行一些預(yù)處理。
五、使用T-SQL語(yǔ)句來(lái)創(chuàng)建觸發(fā)器
基本語(yǔ)句如下:
create trigger trigger_name
on {table_name | view_name}
{for | After | Instead of }
[ insert, update,delete ]
as
sql_statement
六、刪除觸發(fā)器
基本語(yǔ)句如下:
drop trigger trigger_name
七、查看數(shù)據(jù)庫(kù)中已有觸發(fā)器
-- 查看數(shù)據(jù)庫(kù)已有觸發(fā)器
use TestDB
go
select * from sysobjects where xtype='TR'
-- 查看單個(gè)觸發(fā)器
exec sp_helptext '觸發(fā)器名'
八、修改觸發(fā)器
基本語(yǔ)句如下:
alter trigger trigger_name
on {table_name | view_name}
{for | After | Instead of }
[ insert, update,delete ]
as
sql_statement
九、相關(guān)示例
打開(kāi)sqlserver,在右側(cè)"對(duì)象資源管理器”找到需要操作的數(shù)據(jù)庫(kù),點(diǎn)開(kāi)數(shù)據(jù)庫(kù)找到需要?jiǎng)?chuàng)建’觸發(fā)器‘的表,點(diǎn)擊表名左側(cè)的加號(hào),會(huì)出現(xiàn)如下所示
右鍵點(diǎn)擊’觸發(fā)器‘,選擇’新建觸發(fā)器‘
如上圖所示,1后面寫(xiě)上觸發(fā)器名稱,2寫(xiě)上所操作的表名,3,處寫(xiě)上當(dāng)對(duì)表有“何種操作(insert,delete,update)時(shí)觸發(fā)
begin 后開(kāi)始寫(xiě)觸發(fā)后執(zhí)行何種操作。
觸發(fā)器是利用了表數(shù)據(jù)發(fā)生變化時(shí),自動(dòng)生成的兩個(gè)虛擬表,一個(gè)是inserted,一個(gè)是deleted,這兩個(gè)虛擬表從其他地方是檢索不到的,只有觸發(fā)器能讀到。
當(dāng)數(shù)據(jù)發(fā)生變化時(shí),如果是新插入數(shù)據(jù),則該數(shù)據(jù)會(huì)在inserted里面暫時(shí)保存。而刪除一條數(shù)據(jù)時(shí),則會(huì)在deleted里面暫時(shí)保存。更新則等于先刪除再插入,也就是deleted里面存更新前,inserted里面存更新后。這些數(shù)據(jù)會(huì)在觸發(fā)器執(zhí)行完成后消失。
這樣我們需要的數(shù)據(jù)只要從inserted和deleted里面讀取到就可以了。實(shí)例如下:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATETRIGGER [dbo].update_T1_Test
ON dbo.T1
AFTER UPDATE
AS
BEGIN
declare @AA_temp varchar(50);--定義一個(gè)變量
if(UPDATE([AA])) --獲取到T1表字段AA是否是更新
begin
SET NOCOUNT ON;
select @AA_temp = [AA] from inserted; --inserted新插入的數(shù)據(jù)
if(@AA_temp = 'test_a1') --如果更新的值為test_a1則備份數(shù)據(jù)到另外的表T2
begin
insert into T2 (cc, dd) select AA, BB from deleted;
end
end
END
GO
總結(jié)
- 上一篇: WLK防骑拉怪手法(要有序排列再给我答案
- 下一篇: 如何导出元器件清单