觸發器的使用

觸發器的使用

觸發器實質上是特殊類型的存儲過程,當滿足觸發條件時,就可以觸發從而能完成各種不同的管理任務。

概述

觸發器和數據表緊密連在一起,只要談到觸發器,一定是說某個數據表的觸發器。因此,觸發器是在數據表的基礎上進行定義,數據表也成爲觸發器表。觸發器作爲特殊類型的存儲過程,和存儲過程的區別是:存儲過程可以被調用執行,觸發器不可。

觸發器的分類

SQL Server 2008中提供3種類型的觸發器,分別是DML觸發器、DLL觸發器和登錄觸發器。

【DML觸發器】當數據庫中發生數據操作語言事件調用時執行DML觸發器。DML事件包括在指定表或視圖中修改數據的insert語句、update語句或delete語句。一個數據表中可以有多個觸發器。同一類型的觸發器也可以有多個。DML觸發器包括以下類型:

  • AFTER觸發器。在執行insert、update或delete語句操作之後執行after觸發器。比如對某個表中的數據進行了更新操作後,要求立即對相關的表進行指定的操作,這時就可以採用AFTER觸發器。
  • INSTEAD OF觸發器。當對錶進行insert、update或delete操作時,系統不是直接對錶執行這些操作,而是把操作內容交個觸發器,讓觸發器檢查所進行的操作是否正確。如果正確才進行相應的操作。INSTAND OF觸發器的操作有點類似於完整性約束。
  • CLR觸發器。CLR觸發器可以是AFTER觸發器或INSTAND OF觸發器。CLR觸發器還可以是DLL觸發器。CLR觸發器將執行在託管代碼(在.NET Framework中創建並在SQL Server中上載的程序集的成員)中編寫的方法。

【DDL觸發器】響應各種數據定義語言事件,這些事件主要與以關鍵字create、alter和drop開頭的語句對應。

【登錄觸發器】登錄觸發器在遇到login事件時,用戶身份驗證階段完成之後且用戶會話實際建立之前觸發

DLL觸發器的使用

DLL觸發器主要用於創建、刪除或者修改數據庫、數據表等環境。例如,當無意中刪除數據庫或者數據表時,DLL觸發器將提醒操作員,並拒絕刪除操作。

create trigger triggername on database
for drop_table,alter_table
as 
print '對不起,您不能刪除目標數據表!'
rollback

INSTAND OF觸發器的使用

向表“計0261”插入數據時,檢查學號是否存在於表“計026”中,如存在則進行插入操作,否則就不插入。

複製代碼
CREATE TRIGGER [checkid] ON [dbo].[計0261] 
INSTEAD OF insert
AS
IF NOT EXISTS(SELECT * FROM [計026] WHERE 學號=(SELECT 學號 FROM INSERTED))
  BEGIN
    ROLLBACK TRANSACTION
    PRINT '要處理記錄的學號不存在!'
  END
ELSE
  BEGIN
    INSERT INTO 計0261 select * from inserted
    PRINT '已經成功處理記錄!'
  END
複製代碼

AFTER觸發器

對訂貨表設置AFTER觸發器,用量在插入記錄時自動將統計值計算到訂貨統計表中。

複製代碼
CREATE TRIGGER [orderinsert] ON [dbo].[訂貨表]
AFTER INSERT
AS
DECLARE @bookid int, @ordernum int, @num int
SELECT @bookid = 書籍編號, @ordernum = 數量 FROM INSERTED
SELECT @num = count(書籍編號) FROM 訂貨統計表 WHERE 書籍編號=@bookid
IF @num = 0
  --未找到該書,插入記錄
  INSERT INTO 訂貨統計表 VALUES(@bookid, @ordernum)
ELSE
  --找到該書,更新記錄
  UPDATE 訂貨統計表
  SET 總訂貨量 = 總訂貨量 + @ordernum WHERE 書籍編號 = @bookid
複製代碼

DELTED表和INSERTED表

觸發器語句中使用了兩種特殊的表:deleted表和inserted表

deleted表用於存儲delete和update語句所影響的行的原始內容複本。

inserted表用於存儲insert和update語句所影響行的新內容的複本。

 

實例:

複製代碼
create trigger syncBdVendor on AkSupplier
after update,insert
as
declare @Id int,@Name nvarchar(100),@ProductType nvarchar(50),@Address nvarchar(100),@Remark nvarchar(500)
select @Id=Id,@Name=Name,@ProductType=ProductType,@Address=Address,@Remark=Remark from inserted

declare @num int--用於判斷上面的編號是不是存在於BdVendor表中,來推斷添加還是修改
select @num=COUNT(*) from BdVendor where cVenCode=CAST(@Id as nvarchar)

if @num=0
  insert into BdVendor(cVenCode,cVenName,cTrade,cVenAddress,cMemo,dVenCreateDatetime) values (CAST(@Id as nvarchar),@Name,@ProductType,@Address,@Remark,GETDATE())
else
  update BdVendor 
  set cVenName=@Name,cVenAddress=@Address,cMemo=@Remark,dModifyDate=GETDATE()
  where cVenCode=CAST(@Id as nvarchar)
複製代碼

 

 

刪除觸發器

drop trigger syncBarcode

 

 

觸發器使用場景:

    在記錄數據採集內容的時候,採用兩張表,一張表記錄所有數據,還有一張表來記錄單條數據,那麼在做關聯時,保存最新記錄的單條數據表,可以省去不必要的麻煩。記錄單條數據的表通過所有數據的表觸發添加。

複製代碼
ALTER trigger [dbo].[ivUpdateAfterInsert] on [dbo].[AkIv]
after insert
as
--變量
declare    
    @Id bigint=null,--流水號
    @BarCode nvarchar(100)=null,--條碼
    @DateTime datetime=null,--時間
    @Eff decimal(18, 5)=null,--電池轉換效率
    @Isc decimal(18, 5)=null,--短路電流
    @Voc decimal(18, 5)=null,--開路電壓
    @Rs decimal(18, 5)=null,--串聯電阻
    @Rsh decimal(18, 5)=null,--並聯電阻
    @Pmax decimal(18, 5)=null,--最大功率
    @Vpm decimal(18, 5)=null,--最大功率時的電壓
    @Ipm decimal(18, 5)=null,--最大功率時的電流 
    @FF decimal(18, 5)=null,--填充因子
    @Sun decimal(18, 5)=null,--光強
    @Temp decimal(18, 5)=null,--溫度 
    @Class nvarchar(50)=null,--檔位
    @Employee nvarchar(50)=null,--人員
    @LineTitle nvarchar(50)=null,--線別
    @StationTitle nvarchar(50)=null,--工位
    @OrderNumber nvarchar(50)=null,--工單號
    @BatterySupplier nvarchar(50)=null,--電池片廠家代碼
    @Power decimal(18, 2)=null,--電池片功率
    @InterconnectId nvarchar(50)=null,--互連條代碼
    @InterconnectSpec nvarchar(500)=null--互連條規格
--iv數據
select 
    @Id=Id,
    @BarCode=BarCode,
    @DateTime=DateTime,
    @Eff=Eff,
    @Isc=Isc,
    @Voc=Voc,
    @Rs=Rs,
    @Rsh=Rsh,
    @Pmax=Pmax,
    @Vpm=Vpm,
    @Ipm=Ipm,
    @FF=FF,
    @Sun=Sun,
    @Temp=Temp,
    @Class=Class,
    @Employee=Employee,
    @LineTitle=LineTitle, 
    @StationTitle=StationTitle
from inserted

--獲取工單
select @OrderNumber=OrderNumber from AkBarcodeCompInfo where Barcode=@BarCode

--獲取電池片信息
select @BatterySupplier=SupplierCode,@Power=[POWER]
from AkOnLineDetail where AkOnLineDetail.ProductBarcode=@BarCode and MaterialType='電池片'

--獲取互連條信息
select @InterconnectId=MaterialNumber,@InterconnectSpec=MaterialSpec
from AkOnLineDetail where AkOnLineDetail.ProductBarcode=@BarCode and MaterialType='互連條'

--更新
    update AkIv  set 
    OrderNumber=@OrderNumber,
    BatterySupplier=@BatterySupplier,
    Power=@Power,
    InterconnectId=@InterconnectId,
    InterconnectSpec=@InterconnectSpec
    where Id=@Id
    
--插入到單條記錄表中
if not exists (select * from AkIvSingle where BarCode=@BarCode)  
begin
  insert into AkIvSingle(BarCode,DateTime,Eff,Isc,Voc,Rs,Rsh,Pmax,Vpm,Ipm,FF,Sun,Temp,Class,Employee,LineTitle,StationTitle,OrderNumber,BatterySupplier,Power,InterconnectId,InterconnectSpec)
  values (@BarCode,GETDATE(),@Eff,@Isc,@Voc,@Rs,@Rsh,@Pmax,@Vpm,@Ipm,@FF,@Sun,@Temp,@Class,@Employee,@LineTitle,@StationTitle,@OrderNumber,@BatterySupplier,@Power,@InterconnectId,@InterconnectSpec)
end
else
begin
      update AkIvSingle set 
    BarCode=@BarCode,
    DateTime=GETDATE(),
    Eff=@Eff,
    Isc=@Isc,
    Voc=@Voc,
    Rs=@Rs,
    Rsh=@Rsh,
    Pmax=@Pmax,
    Vpm=@Vpm,
    Ipm=@Ipm,
    FF=@FF,
    Sun=@Sun,
    Temp=@Temp,
    Class=@Class,
    Employee=@Employee,
    LineTitle=@LineTitle,
    StationTitle=@StationTitle,
    OrderNumber=@OrderNumber,
    BatterySupplier=@BatterySupplier,
    Power=@Power,
    InterconnectId=@InterconnectId,
    InterconnectSpec=@InterconnectSpec
    where BarCode=@BarCode
end
發佈了24 篇原創文章 · 獲贊 22 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章