qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

          SQL Server2005中觸發(fā)器的運(yùn)用

            編寫過存儲過程的人,再編寫觸發(fā)器時會發(fā)現(xiàn):他們的語法、格式是非常類似的。其實(shí)觸發(fā)器就是一種特殊類型的存儲過程。他們都是預(yù)編譯的,在程序正式編譯前就由編譯器進(jìn)行編譯,存儲在服務(wù)器端。

            不過,觸發(fā)器與一般的存儲過程也有些區(qū)別。觸發(fā)器主要是通過對數(shù)據(jù)庫的增刪改的操作,或者是一個觸發(fā)動作的觸發(fā)作用等事件觸發(fā)而被執(zhí)行;而存儲過程則是通過像傳遞SQL語句一樣,傳遞存儲過程的名字來被程序調(diào)用,實(shí)現(xiàn)功能。

            觸發(fā)器一共分為五種類型:Update觸發(fā)器,Insert觸發(fā)器、Delete觸發(fā)器、Instead of觸發(fā)器和After觸發(fā)器。前三個分別是相應(yīng)表上進(jìn)行更新、插入、刪除操作時觸發(fā)。Instead of觸發(fā)器在不執(zhí)行插入、更新或刪除操作時觸發(fā)。

            在觸發(fā)器中存在兩個虛擬表:Inserted表和Deleted表。Inserted表保存的是Insert或Update之后所影響的記錄形成的表,Deleted保存的是Delete或update之前所影響的記錄形成的表。這兩個表是邏輯表,這兩個表是動態(tài)駐留在內(nèi)存中的,當(dāng)觸發(fā)器工作完成,這兩個表也被刪除。

            觸發(fā)器的創(chuàng)建代碼格式:

          CREATE TRIGGER trigger_name      --觸發(fā)器的名字
          ON table|view [WITH ENCRYPTION]  --在哪個表上創(chuàng)建觸發(fā)器
          { FOR | AFTER | INSTEAD OF }    
          {[INSERT][,][UPDATE][,][DELETE]} --激活觸發(fā)器的類型
          AS sql_statements […n]

            代碼中關(guān)鍵字for、after、Insteadof分別代表不同的使用范圍:

            for表示為AFTER觸發(fā)器,且該類型觸發(fā)器僅能在表上創(chuàng)建;

            after表示只有在執(zhí)行了指定的操作INSERT、DELETE、UPDATE之后觸發(fā)器才被激活,執(zhí)行觸發(fā)器中的SQL語句;

            instead of當(dāng)為表或視圖定義了針對某一操作INSERT、DELETE、UPDATE的INSTEAD OF 類型觸發(fā)器,且執(zhí)行了相應(yīng)的操作時,盡管觸發(fā)器被觸發(fā),但相應(yīng)的操作并不被執(zhí)行,而運(yùn)行的僅是觸發(fā)器SQL語句本身。

            下面說下觸發(fā)器的作用:

            1、級聯(lián)修改數(shù)據(jù)庫中的相關(guān)的表;

            看下面的牛腩新聞發(fā)布系統(tǒng)的例子:其中一個新聞類別(Category)對應(yīng)多個或者0條新聞;一條新聞(news)對應(yīng)著多個或者0個新聞評論(comment)。

          set ANSI_NULLS ON
          set QUOTED_IDENTIFIER ON
          go
          -- =============================================
          -- Author:  劉正權(quán)
          -- Create date: 2008-11-15 11:13
          -- Description: 刪除新聞類別觸發(fā)器
          -- =============================================
          CREATE TRIGGER trigCategoryDelete
             ON  category
             instead of DELETE
          AS
          BEGIN
          --刪除新聞,再在類別表中刪除--觸發(fā)器實(shí)現(xiàn)
           declare @caId int
           select @caId=id from deleted
           --刪除評論(選出多條用in,一條用=號)
           delete comment where newsId in (select newsId from news wherecaId=@caId)
           --刪除新聞
           delete news wherecaId=@caId
           --刪除類別
           delete category whereid=@caId
          END

            2、執(zhí)行比核查約束更為復(fù)雜的約束操作;在觸發(fā)器中可以書寫更為復(fù)雜的SQL語句,例如可以引用多個表,并使用if……else等語句做更復(fù)雜的檢查。

            下面看下例子:如果更改了學(xué)生的學(xué)號,則他的借書記錄表中記錄也同時更新。

            這時候,我們可以建立一下觸發(fā)器:

          SET ANSI_NULLS ON
          GO
          SET QUOTED_IDENTIFIER ON
          GO
          -- =============================================
          -- Author:  劉正權(quán)
          -- Create date:2012-4-22
          -- Description: 更改了學(xué)生的學(xué)號,則他的借書記錄表中記錄也同時更新
          -- =============================================
          Create Trigger truStudent
          On Student        --在Student表中創(chuàng)建觸發(fā)器
          for Update        --為什么事件觸發(fā)
          As                --事件觸發(fā)后所要做的事情
          if Update(StudentID)           
          begin

          Update BorrowRecord
          Set StudentID=i.StudentID
          From BorrowRecord br , Deleted   d ,Inserted i  --Deleted和Inserted臨時表
          Where br.StudentID=d.StudentID
          end 





            3、拒絕或回滾違反引用完整性的操作。檢查對數(shù)據(jù)庫的操作是否違反引用完整性,并選擇相應(yīng)的操作;

            看下面的例子:不允許刪除任何銷售記錄大于等于20條的商店。

          SET ANSI_NULLS ON
          GO
          SET QUOTED_IDENTIFIER ON
          GO
          -- =============================================
          -- Author:  劉正權(quán)
          -- Create date: 2012-4-22
          -- Description: 不允許刪除任何銷售記錄大于等于20條的商店
          -- =============================================
          CREATE TRIGGER trDelSales
             ON  tblSales  
             for Delete
          AS 
           if(select Count(*) from Deleted 
           where Deleted.qty>=20)>0
          BEGIN
           print'您不能刪除任何記錄'
           rollback transaction   --事務(wù)回滾
          END
          GO

            4、比較表修改前后數(shù)據(jù)之間的差別,并根據(jù)差別才去相應(yīng)的操作。

            例如:若想規(guī)定每次工資的變動幅度不能超過40%,使用觸發(fā)器可以將修改后的表數(shù)據(jù)和修改前的表數(shù)據(jù)進(jìn)行比較,若超出40%,可以回滾該修改操作。

            觸發(fā)器是自動觸發(fā)的,一旦對表中的數(shù)據(jù)做了修改,該觸發(fā)器將立即被激活,充分體現(xiàn)了觸發(fā)的優(yōu)勢,保持了數(shù)據(jù)的完整性;然而,觸發(fā)器性能通常是比較低的。

            當(dāng)運(yùn)行觸發(fā)器時,系統(tǒng)處理的大部分時間花費(fèi)在參照它表達(dá)的這一處理上,因?yàn)檫@些表達(dá)既不在內(nèi)存中,也不在數(shù)據(jù)庫設(shè)備上,而邏輯表(刪除表和插入表)總是位于內(nèi)存中。所以觸發(fā)器參照的其他表的位置決定了操作花費(fèi)時間的長短。

          posted on 2012-06-21 10:00 順其自然EVO 閱讀(2764) 評論(2)  編輯  收藏 所屬分類: 數(shù)據(jù)庫

          評論

          # re: SQL Server2005中觸發(fā)器的運(yùn)用 2013-08-12 15:48 yeungll

          good  回復(fù)  更多評論   

          # re: SQL Server2005中觸發(fā)器的運(yùn)用 2013-08-12 15:49 yeungll

          可以  回復(fù)  更多評論   

          <2012年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 上林县| 中超| 手机| 辛集市| 晴隆县| 和顺县| 塔城市| 潞城市| 通州市| 贵港市| 衡山县| 渝北区| 孝感市| 察隅县| 阿鲁科尔沁旗| 临汾市| 中卫市| 新龙县| 常德市| 长兴县| 永清县| 视频| 汝南县| 上饶县| 阿勒泰市| 桂阳县| 香河县| 竹山县| 昂仁县| 长宁区| 保靖县| 民乐县| 启东市| 顺昌县| 剑河县| 甘谷县| 康马县| 山丹县| 永胜县| 临夏县| 永寿县|