SqlCollections - 觸發器

  1 --==============================觸發器===============================
  2 --分類及注意
  3 --觸發器分爲DML觸發器和DDL觸發器,DML觸發器又分After觸發器和Instead Of觸發器
  4 --After觸發器只能夠建在表上,Instead Of觸發器能夠建在表或視圖上
  5 --每一個觸發器都定義了插入表Inserted和刪除表Deleted,存在於服務器內存中,不是物理表
  6 --Truncate Table語句不會激發Delete類型觸發器
  7 
  8 --After觸發器
  9 --例:插入一條記錄時,顯示友好提示
 10 CREATE TRIGGER 產品_Insert1
 11 ON 產品    --ON+表名或視圖名(是有Instead Of觸發器能夠建在視圖上)
 12 AFTER INSERT
 13 AS
 14 BEGIN
 15     PRINT '又添加了一種產品(1)!'
 16 END
 17 GO
 18 --再建立一個
 19 CREATE TRIGGER 產品_Insert2
 20 ON 產品
 21 AFTER INSERT
 22 AS
 23 BEGIN
 24     PRINT '又添加了一種產品(2)!'
 25 END
 26 GO
 27 /*顯示:又添加了一種產品(1)!
 28         又添加了一種產品(2)!*/
 29 INSERT INTO 產品(產品名稱) VALUES ('小蘋果')    
 30 
 31 --After觸發器的激活順序
 32 --參數1:觸發器名,注意引號;
 33 --參數2:激活次序,包括First,Last,None,None表明不指定;
 34 --參數3:激活動做,能夠爲Insert,Update或Delete
 35 EXEC sp_settriggerorder '產品_Insert1','Last','Insert'
 36 GO
 37 EXEC sp_settriggerorder '產品_Insert2','First','Insert'
 38 GO
 39 /*顯示:又添加了一種產品(2)!
 40         又添加了一種產品(1)!
 41 順序已經反了*/
 42 INSERT INTO 產品(產品名稱) VALUES ('小蘋果')    
 43 
 44 --在After觸發器中回滾
 45 --例:插入記錄時,若折扣大於0.6,則執行回滾不插入
 46 CREATE TRIGGER 訂單明細_Insert
 47 ON 訂單明細
 48 AFTER INSERT
 49 AS
 50 BEGIN
 51     IF(SELECT 折扣 FROM INSERTED) > 0.6    --INSERTED:存放新紀錄的表,DELETED:存放舊記錄的表
 52     BEGIN
 53         PRINT '折扣不容許大於0.6!'
 54         ROLLBACK TRAN    --回滾操做
 55     END
 56 END
 57 GO
 58 INSERT INTO 訂單明細(訂單ID,產品ID,單價,數量,折扣)
 59 VALUES(11077,1,18,1,0.8)
 60 GO
 61 --數據被回滾,未成功插入
 62 SELECT * FROM 訂單明細 WHERE 訂單ID = 11077 AND 折扣=0.8
 63 
 64 --Instead Of觸發器
 65 --上一例用Instead Of觸發器更好,在插入前先判斷,減小服務器負擔
 66 CREATE TRIGGER 訂單明細_Insert2
 67 ON 訂單明細
 68 INSTEAD OF INSERT
 69 AS
 70 BEGIN
 71     DECLARE @訂單ID int,
 72     @產品ID int,
 73     @單價 money,
 74     @數量 smallint,
 75     @折扣 real;
 76     SELECT @訂單ID = 訂單ID FROM inserted
 77     SELECT @產品ID = 產品ID FROM inserted
 78     SELECT @單價 = 單價 FROM inserted
 79     SELECT @數量 = 數量 FROM inserted
 80     SELECT @折扣 = 折扣 FROM inserted
 81     IF(@折扣 > 0.6)
 82         BEGIN
 83             PRINT '折扣不容許大於0.6!'
 84         END
 85     ELSE
 86         BEGIN
 87             INSERT INTO 訂單明細(訂單ID,產品ID,單價,數量,折扣)
 88             VALUES(@訂單ID,@產品ID,@單價,@數量,@折扣)
 89         END
 90 END
 91 GO
 92 INSERT INTO 訂單明細(訂單ID,產品ID,單價,數量,折扣)
 93 VALUES(11077,1,18,1,0.9)
 94 GO
 95 --數據被回滾,未成功插入
 96 SELECT * FROM 訂單明細 WHERE 訂單ID = 11077 AND 折扣=0.9
 97 
 98 --查看指定觸發器信息
 99 EXEC sp_help '訂單明細_Insert'    --簡要信息
100 EXEC sp_helptext '訂單明細_Insert'    --具體腳本
101 
102 --重命名觸發器
103 EXEC sp_rename '訂單明細_Insert','訂單明細_Insert1'
104 
105 --刪除觸發器
106 --刪除表時會自動刪除該表的觸發器
107 DROP TRIGGER 訂單明細_Insert1    --注意不能帶引號
108 
109 --啓用與禁用觸發器
110 ALTER TABLE 訂單明細
111 DISABLE TRIGGER 訂單明細_Insert2    --禁用
112 --ENABLE TRIGGER 訂單明細_Insert2    --啓用
113 --ENABLE TRIGGER ALL    --啓用全部
114 
115 --DDL觸發器
116 --DDL觸發器只能定義FOR或AFTER(意義同樣),不能定義Instead Of
117 CREATE TRIGGER 禁止修改或刪除該數據庫的表
118 ON DATABASE    --ON後面可跟DATABASE,做用到當前數據庫,或跟ALL SERVER,做用到當前服務器的全部數據庫
119 FOR ALTER_TABLE,DROP_TABLE    --看成用在ALL SERVER時,能夠FOR DROP_DATABASE等
120 AS
121 BEGIN
122     PRINT '不容許操做數據表!'
123     ROLLBACK TRAN
124 END
125 GO
126 DROP TABLE tbl1
127 
128 --建立自定義數據庫日誌
129 --建立日誌記錄表
130 CREATE TABLE 日誌記錄表
131 (
132     編號 int IDENTITY(1,1) PRIMARY KEY NOT NULL,
133     事件 varchar(5000) NULL,
134     所用語句 varchar(5000) NULL,
135     操做者 varchar(50) NULL,
136     操做時間 datetime NULL
137 )
138 GO
139 --建立DDL觸發器
140 CREATE TRIGGER 記錄日誌
141 ON DATABASE
142 FOR DDL_DATABASE_LEVEL_EVENTS
143 AS
144 BEGIN
145     DECLARE @log XML
146     DECLARE @event varchar(5000)
147     DECLARE @sql varchar(5000)
148     DECLARE @operator varchar(50)
149     SET @log = EVENTDATA()
150     SET @event = @log.value('(EVENT_INSTANCE/EventType)[1]','nvarchar(100)')
151     SET @sql = @log.value('(/EVENT_INSTANCE/TSQLCommand)[1]','nvarchar(2000)')
152     SET @operator = CONVERT(varchar(50),CURRENT_USER)
153     --插入日誌表
154     INSERT INTO 日誌記錄表(事件,所用語句,操做者,操做時間)
155     VALUES(@event,@sql,@operator,GETDATE())
156 END    
157 GO
158 --驗證日誌
159 CREATE TABLE 測試日誌表(編號 int PRIMARY KEY,測試內容 varchar(50))
160 GO
161 --先把以前的DDL觸發器禁用掉
162 DISABLE TRIGGER 禁止修改或刪除該數據庫的表 ON DATABASE    --禁用DDL觸發器的寫法
163 GO
164 --刪除表
165 DROP TABLE 測試日誌表
166 GO
167 --查看日誌
168 SELECT * FROM 日誌記錄表
169 
170 --判斷字段是否被更改
171 CREATE TRIGGER 看折扣是否被更改
172 ON 訂單明細
173 AFTER UPDATE
174 AS
175 BEGIN
176     IF UPDATE(折扣)    --該字段是否被更新
177     BEGIN
178         PRINT '折扣字段將被修改'
179     END
180     ELSE
181     BEGIN
182         PRINT '折扣字段沒有被修改'
183     END
184 END
185 GO
186 --輸出:折扣字段將被修改
187 UPDATE 訂單明細 SET 折扣 = 0.2 WHERE 訂單ID = 1 AND 產品ID = 1
188 --輸出:折扣字段沒有被修改
189 UPDATE 訂單明細 SET 數量 = 1 WHERE 訂單ID = 1 AND 產品ID = 1
190 --輸出:折扣字段將被修改
191 UPDATE 訂單明細 SET 折扣 = 0.2,數量 = 1 WHERE 訂單ID = 1 AND 產品ID = 1
相關文章
相關標籤/搜索