亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

雜談--DML觸發器學習

2024-07-21 02:48:03
字體:
來源:轉載
供稿:網友
雜談--DML觸發器學習

觸發器按類型分為三類:

1. DML 觸發器,在數據變更時觸發;

2. DDL 觸發器,在修改數據庫級別或實例級別對象時觸發;

3. Login 觸發器,在用戶登錄時觸發;

最常見的是DML觸發器,DML觸發器又可以分為兩類: INSTEAD OF觸發器和AFTER觸發器(部分書上有提到FOR觸發器,其實就是AFTER 觸發器,只是寫法不同而已)。

從功能來看,INSTEAD OF觸發器用來替換實際的數據修改操作,而AFTER觸發器用來在實際操作完成后進行后續操作。例如對于DELETE操作,如果我們期望只修改數據狀態來標示數據已被刪除而不是將數據從表中刪除,那么我們可以使用INSTEAD OF觸發器來實現;如果我們期望在刪除數據后在其他表記錄刪除操作的發生時間,那么我們可以使用AFTER觸發器來實現。

從執行來看,INSTEAD OF觸發器和AFTER觸發器的所處的執行時期不同,SQL Server中的觸發順序為:

1. 觸發INSTEAD OF觸發器

2. 觸發DEFAULT 約束

3. 觸發主鍵/唯一/CHECK約束

4. 觸發外鍵約束

5. 觸發AFTER 觸發器

因此如果期望修改操作順利執行而不觸發約束導致回滾的話,可以使用INSTEAD OF觸發器來將實現(在INSTEAD OF 觸發器中修改使數據滿足約束條件)。

因為INSTEAD OF 觸發器改寫了實際要發生的修改操作,因此每個表上每種修改類型(DELETE/INSERT/UPDATE)只能有一個INSTEAD OF 觸發器;而AFTER 觸發器沒有類似限制,可以創建多個AFTER觸發器。

問題來了,在存在多個AFTER觸發器情況下,AFTER觸發器按什么順序來執行呢?SQL Server允許針對每種修改類型(DELETE/INSERT/UPDATE)指定一個最先觸發和最后觸發的AFTER觸發器,但不能控制其余的觸發器觸發順序。

指定最先執行的AFTER觸發器:

--指定針對INSERT操作最先觸發的AFTER觸發器EXEC sys.sp_settriggerorder@triggername='tr_TB1_INSERT',@order='First',@stmttype='INSERT'

說完觸發順序,再來說道說道觸發次數,裝逼的說法為:DML trrigers have statement scope and only fire just once regardless of how many rows affected.通俗說法就是對于一條語句,不管語句修改了多少行(0行或者1000行),對應該操作類型的觸發器都會被觸發并且只觸發一次。

PS:上面說的Fire only once只是針對執行的SQL語句,并不包含該觸發器內部的SQL語句

SQL server中有兩種特殊的觸發器:嵌套(Nested)觸發器和遞歸(Recursive)觸發器,由Demo來解釋下:

嵌套(Nested)觸發器:在TB1和TB2上創建觸發器,當TB1上TR_TB1_INSERT1被觸發時,TR_TB1_INSERT1中的語句執行導致TB2上TR_TB2_INSERT1被觸發

--================================--在TB1和TB2上創建觸發器,當TB1上TR_TB1_INSERT1被--觸發時,TR_TB1_INSERT1中的語句執行導致TB2上--TR_TB2_INSERT1被觸發,即屬于Nested觸發器CREATE TRIGGER TR_TB1_INSERT1ON dbo.TB1AFTER INSERTASBEGININSERT INTO TB2(C1)SELECT C1 FROM insertedENDGOCREATE TRIGGER TR_TB2_INSERT1ON dbo.TB2AFTER INSERTASBEGINSELECT 1END

遞歸(Recursive)觸發器可分為直接遞歸(Directed Recursive)觸發器和間接遞歸(Indirect Recursive)觸發器

直接遞歸(Directed Recursive)觸發器:

在TB1創建觸發器,當TB1上TR_TB1_INSERT1被觸發時,TR_TB1_INSERT1中的語句執行導致TB1上TR_TB1_INSERT1再次被觸發

--================================--在TB1創建觸發器,當TB1上TR_TB1_INSERT1被觸發時,--TR_TB1_INSERT1中的語句執行導致TB1上TR_TB1_INSERT1--再次被觸發,即屬于直接遞歸(Directed Recursive)觸發器。ALTER TRIGGER TR_TB1_INSERT1ON dbo.TB1AFTER INSERTASBEGIN--限制遞歸層數為10層    IF(@@NESTLEVEL<10)    BEGIN        INSERT INTO TB1(C1)        SELECT C1+1 FROM inserted    ENDENDGO

間接遞歸(Indirect Recursive)觸發器:

在TB1和TB2上創建觸發器,當TB1上TR_TB1_INSERT1被觸發時,TR_TB1_INSERT1中的語句執行導致TB2上TR_TB2_INSERT1被觸發,而TB2上TR_TB2_INSERT1的觸發器執行時又導致TB1上TR_TB1_INSERT1被觸發,從而引發循環。

--================================--在TB1和TB2上創建觸發器,當TB1上TR_TB1_INSERT1被--觸發時,TR_TB1_INSERT1中的語句執行導致TB2上--TR_TB2_INSERT1被觸發,而TB2上TR_TB2_INSERT1的--觸發器執行時又導致TB1上TR_TB1_INSERT1被觸發,從而--引發循環,即間接遞歸(Indirect Recursive)觸發器CREATE TRIGGER TR_TB1_INSERT1ON dbo.TB1AFTER INSERTASBEGIN    IF(@@NESTLEVEL<10)    BEGIN        INSERT INTO TB2(C1)        SELECT C1 FROM inserted    ENDENDGOCREATE TRIGGER TR_TB2_INSERT1ON dbo.TB2AFTER INSERTASBEGIN    IF(@@NESTLEVEL<10)    BEGIN        INSERT INTO TB1(C1)        SELECT C1 FROM inserted    ENDEND

需要注意的是:

1. 嵌套(Nested)觸發器在sys.configurations中配置,默認開啟

2. (Recursive)觸發器在數據庫級別配置,默認為關閉,即不允許直接遞歸(Directed Recursive)觸發器,但不影響間接遞歸(Indirect Recursive)觸發器,如果需要禁用遞歸(Indirect Recursive)觸發器,需要同時禁用嵌套(Nested)觸發器和(Recursive)觸發器

3. 由于嵌套觸發器會消耗大量資源(需要保留每層觸發器的上下文以便回滾),因此默認限制最多嵌套32層。

行版本(Row version)

在SQL Server多中功能中使用到row version來保留多個版本的數據,這些功能有:

1. MARS

2. Triggers

3. Online indexing

4. Optimistic Transaction Isolation Levels

因此在使用觸發器時,應考慮到可能會為表增加額外14bytes的行版本存儲指針

如下面例子中,表中數據被刪除一半,但由于數據只是表示為gost,尚未真正移除,而由于觸發器存在,每行額外增加14byte的數據,從而導致頁拆分,最終使得刪除操作完成后表反而增大。

測試代碼:

USE tempdb--================================--創建測試表DROP TABLE TB1GOCREATE TABLE TB1(    ID INT IDENTITY(1,1) PRIMARY KEY,    C2 INT NOT NULL,    C3 VARCHAR(MAX))GO--================================--創建Delete觸發器CREATE TRIGGER TR_TB1_DELETEON dbo.TB1AFTER DELETEASBEGINRETURN ENDGO--================================--插入5w數據INSERT INTO TB1(C2)SELECT TOP(5000) 1 AS C2 FROM sys.all_columns TGO 10--================================--查看表TB1使用的頁DBCC TRACEON(3604)GODBCC IND('tempdb','TB1',1)GO--================================--刪除一半的數據DELETE FROM  dbo.TB1WHERE ID%2=0GO--================================--查看表TB1使用的頁DBCC TRACEON(3604)GODBCC IND('tempdb','TB1',1)GO

PS: 如果表中不存在LOB或者VARCHAR(MAX)之類的大字段,不存在ROW_OVERFLOW數據頁,則SQL Server不會為每行增加14byte的行版本存儲指針

--==============================================================

--額外補充

1. 如果使用Merge并且設置了INSERT/DELETE/UPDATE方法,那么即使沒有滿足條件的數據進行INSERT/DELETE/UPDATE,也會觸發INSERT/DELETE/UPDATE相關的觸發器。

--==================================================

新一年,換換口味,來點萌妹子吧!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲电影免费观看| 日本免费一区二区三区视频观看| 国产91ⅴ在线精品免费观看| 国产成人高清激情视频在线观看| 97超级碰碰碰久久久| 亚洲女同性videos| 成年无码av片在线| 亚洲精品国产综合区久久久久久久| 91亚洲精品视频| 91精品久久久久久久久久久久久久| 91亚洲午夜在线| 亚洲日本aⅴ片在线观看香蕉| 成人精品久久一区二区三区| 九九热精品视频在线播放| 久久久精品国产亚洲| 亚洲成人精品久久| 久久久999精品免费| 最近2019中文字幕第三页视频| 精品成人久久av| 亚洲欧美日韩一区在线| 欧美成人午夜视频| 日韩男女性生活视频| 国内免费久久久久久久久久久| 久久久999精品| 国产有码一区二区| 国产精品久久久久一区二区| 久久久久久久久久亚洲| 精品国产一区二区三区久久狼5月| 中文字幕日韩欧美| 亚洲第一精品福利| 成人情趣片在线观看免费| 92福利视频午夜1000合集在线观看| 久久国产天堂福利天堂| 国产精品自产拍在线观看| 国产一区二区黑人欧美xxxx| 国产成人福利夜色影视| 国产日韩欧美自拍| 久久午夜a级毛片| 自拍偷拍亚洲在线| 欧美极品美女视频网站在线观看免费| 日韩av在线导航| 久久成人精品一区二区三区| 国产日韩中文在线| 国产精品视频白浆免费视频| 久国内精品在线| 国产成人啪精品视频免费网| 久久亚洲电影天堂| 日韩成人av网址| 欧美精品免费在线观看| 久国内精品在线| 亚洲一区二区久久久久久久| 欧美日韩免费观看中文| 国产999精品久久久影片官网| 久久久久久国产精品三级玉女聊斋| 国色天香2019中文字幕在线观看| 2019av中文字幕| 国产成人精品av在线| 91在线视频一区| 欧美激情视频三区| 色综合视频一区中文字幕| 日韩精品极品视频| 色噜噜久久综合伊人一本| 午夜精品福利电影| 亚洲免费小视频| 久久亚洲综合国产精品99麻豆精品福利| 日韩激情av在线免费观看| 91精品啪在线观看麻豆免费| 亚洲国产中文字幕久久网| 韩剧1988在线观看免费完整版| 亚洲天堂视频在线观看| 日韩欧美在线第一页| 欧美美女18p| 51精品国产黑色丝袜高跟鞋| 国产精品久久久久久久久久99| 中文字幕精品www乱入免费视频| 中文字幕日韩av综合精品| 精品日本高清在线播放| 亚洲精品有码在线| 亚洲а∨天堂久久精品9966| 亚洲aⅴ男人的天堂在线观看| 国内精品小视频| 日韩在线高清视频| 色婷婷av一区二区三区在线观看| 亚洲伊人成综合成人网| 韩国福利视频一区| 国产精品成久久久久三级| 国产一区二区三区免费视频| 国产成人精品一区二区在线| 午夜精品在线观看| 国产999精品久久久| 国产成人avxxxxx在线看| 久久免费视频网站| 欧美国产精品日韩| 亚洲无亚洲人成网站77777| 91亚洲精品久久久久久久久久久久| 精品国产一区二区三区四区在线观看| 88xx成人精品| 欧美精品激情blacked18| 国产精品综合网站| 亚洲人成电影网站色…| 爱福利视频一区| 午夜精品一区二区三区在线| 国产精品69久久| 91九色国产社区在线观看| 亚洲自拍偷拍一区| 亚洲www在线观看| 欧美性猛交xxx| 国产精品亚洲激情| 韩国三级日本三级少妇99| 亚洲精品av在线| 国产成人精品优优av| 久久影院免费观看| 亚洲成人中文字幕| 成人亚洲激情网| 欧美成人性色生活仑片| 美女视频久久黄| 成人国产精品久久久久久亚洲| 国产成人在线一区二区| 中文字幕免费国产精品| 久久国内精品一国内精品| 日韩免费观看在线观看| 91亚洲国产成人精品性色| 福利二区91精品bt7086| 国产精品日韩在线一区| 91精品国产综合久久香蕉的用户体验| 亚洲高清一区二| 伊人久久男人天堂| 国产亚洲欧洲高清| 欧美日韩激情视频8区| 精品中文字幕在线观看| 久久久精品一区| 亚洲精品久久久久中文字幕欢迎你| 中文字幕欧美精品日韩中文字幕| 欧洲亚洲免费在线| 欧美精品videos性欧美| 日韩电影第一页| 中文字幕最新精品| 久久精品亚洲一区| 久久露脸国产精品| 亚洲国产另类久久精品| 国产精品色悠悠| 国产成+人+综合+亚洲欧美丁香花| 国模吧一区二区三区| 蜜月aⅴ免费一区二区三区| 欧美大片欧美激情性色a∨久久| 538国产精品一区二区免费视频| 久久av中文字幕| 一本一道久久a久久精品逆3p| 在线精品国产成人综合| 欧美理论电影在线观看| 欧美国产日韩一区二区在线观看| 日韩美女免费线视频| 亚洲91av视频| 亚洲国产精品小视频| 91九色国产在线| 97视频免费在线看| 欧美裸体xxxx| 欧美精品在线观看| 欧美人与性动交a欧美精品| 日韩中文字幕精品视频| 91国偷自产一区二区三区的观看方式| 欧美午夜电影在线| 青草热久免费精品视频| 色婷婷综合成人av|