在開發過程中,最好不要有過多的觸發器,要謹慎使用,因為觸發器會有不同觸發的渲染效果,不停的觸發下去。
例如:假設我們做了一個觸發器,刪A自動刪B,但如果有人在B表也寫了一個觸發器,刪B自動刪C,又有一個人也寫了刪C自動刪D,這樣一系列的觸發,就會發生不好的事情,你刪了A表的一個數據,結果BCD表都被觸發了,BCD的數據也都被刪了,這樣就造成了數據的丟失了。業務邏輯可能本身只是希望A刪掉的同時把B刪掉,這樣就結束完了,但由於觸發器太多,造成A刪掉的同時,BCD很多數據都同時被刪掉,數據沒了很危險,要謹慎使用。
Trigger 觸發程序(觸發器)
Trigger 觸發程序:(1)instead of觸發器 (2)After觸發器
instead of觸發器:在執行操作之前被執行After觸發器:在執行操作之後被執行
instead of觸發器:
instead of delete:刪除前觸發
After觸發器:
after insert:新增後觸發after delete:刪除後觸發after update修改後進行觸發
alter trigger:修改觸發器drop trigger 觸發程序名:刪除觸發程序
Trigger inserted & deleted Table (暫存表)
after insert新增後觸發after delete:刪除後觸發- 從 inserted 暫存表取得id:
select DepartmentId from inserted即將要新增的編號。 - 從 deleted 暫存表取得id:
select DepartmentId from deleted即將要刪除的編號。
deleted Table和 inserted Table 為 Triiger 使用的兩個特殊暫存資料表(交易紀錄的檢視表),其欄位名稱、順序和資料型態都跟原來的 Table 一致,可以利用它們了解 INSERT、UPDATE 和 DELETE T-SQL 語法觸發 Triiger 時,插入、修改或是刪除哪些資料。
inserted Table會儲存INSERT和UPDATE前的資料deleted Table則會儲存UPDATE後和DELETE的資料。
[SQL] Trigger - inserted & deleted Table
語法:
create trigger:建立一個觸發器after:事後觸發after insert:新增後觸發
1
2
3
4
5
6
7
8
9
10
create trigger tri_InsertPeople on People after insert
as
--as後面開始寫 業務邏輯代碼
go
--create trigger 創建一個觸發器
--tri_InsertPeople 觸發器名稱
--on People --觸發器在People資料表裡面
--在People資料表裡面做什麼事情才會觸發呢?
--after insert 在插入數據之後才會觸發
--在as之後就要寫業務邏輯代碼了
範例1:after insert-新增員工時若部門不存在,則自動新增部門資料
(1)假如有部門表和員工表,在新增員工的時候,該員工的部門編號如果在部門表找不到(事前或事後觸發都可以),則自動新增部門資料,部門名稱為”新部門”。
先建立測試數據
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
--部門
create table Department
(
DepartmentId varchar(10) primary key,
DepartmentName nvarchar(50)
)
--人員信息
create table People
(
PeopleId int primary key identity(1,1),
DepartmentId varchar(10),--部門編號,外鍵
PeoplenName nvarchar(20),
PeopleSex nvarchar(2),
PeoplePhone nvarchar(20)
)
insert into Departmentt(DepartmentId,DepartmentName)
values('001','總經辦'),('002','市場部'),('003','人事部'),('004','軟體部'),('005','摸魚部')
insert into People(DepartmentId,PeoplenName,PeopleSex,PeoplePhone)
values('001','劉備','男','0988111222'),
('001','關羽','男','0988999888'),
('002','張飛','男','0988000555')
語法
create trigger:建立一個觸發器after:事後觸發after insert:新增後觸發
1
2
3
4
create trigger tri_InsertPeople on People after insert
as
--as後面開始寫 業務邏輯代碼
go
- create trigger 創建一個觸發器
- tri_InsertPeople 觸發器名稱
- on People –觸發器在People資料表裡面
- 在People資料表裡面做什麼事情才會觸發呢?
- after insert 在插入數據之後才會觸發
- 在as之後就要寫業務邏輯代碼了
實作
(1) 建立觸發器 create trigger
(2) 判斷員工編號是否存在 if not exists
if not exists(select * from Department where DepartmentId = 新增員工的時候的部門編號)
(3) 不存在就建立新部門
insert into Departmentt(DepartmentId,DepartmentName) values('??','新部門')
(4) 但我們不知道id是什麼,就把拿剛查的inserted暫存表的來用:
select DepartmentId from inserted(即將要新增的編號)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--(1)假如有部門表和員工表,在新增員工的時候,該員工的部門編號如果在部門表找不到(事前或事後觸發都可以)
--則自動新增部門資料,部門名稱為"新部門"
create trigger tri_InsertPeople on People after insert
as
--判斷員工編號是否存在,如果不存在
if not exists(select * from Department where DepartmentId = (select DepartmentId from inserted))
begin
--新增部門
insert into Department(DepartmentId,DepartmentName)
values((select DepartmentId from inserted),'新部門')
end
go
--測試觸發器
insert into People(DepartmentId,PeoplenName,PeopleSex,PeoplePhone)
values('004','Ken','男','0988111222')
insert into People(DepartmentId,PeoplenName,PeopleSex,PeoplePhone)
values('006','VVI','男','0988111222')
deleted Table和 inserted Table 為 Triiger 使用的兩個特殊暫存資料表(交易紀錄的檢視表),其欄位名稱、順序和資料型態都跟原來的 Table 一致,可以利用它們了解 INSERT、UPDATE 和 DELETE T-SQL 語法觸發 Triiger 時,插入、修改或是刪除哪些資料。
inserted Table會儲存INSERT和UPDATE前的資料deleted Table則會儲存UPDATE後和DELETE的資料。
[SQL] Trigger - inserted & deleted Table
範例2:after delete-刪除一個部門的時候,同時刪除其下的員工
after: 事後觸發after delete:刪除後觸發
1
2
3
4
5
6
7
8
9
--(2)觸發器實現,刪除一個部門的時候,將部門下所有的員工全部刪除
create trigger tri_DeleteDept on Department after delete
as
--觸發的內容
--delete from People where DepartmentId = 刪除的部門編號
delete from People where DepartmentId = (select DepartmentId from deleted)
go
--測試觸發器
delete from Department where DepartmentId = '006'
deleted Table則會儲存UPDATE後和DELETE的資料。
範例3:instead of delete-刪除一個部門的時候,其下有員工就不刪除
instead delete:事前觸發- 部門還沒刪除的時候,進行一個判斷,所以要使用
instead of delete - 判斷該部門下是否有員工
if exists(select * from People where DepartmentId = 將要刪除的部門編號) - 將要刪除的部門編號,可以用
deleted Table暫存表來查:
即將要刪除的編號select DepartmentId from deleted - 部門下不存在員工,才要刪除部門,if exists 可以改成
if not exists
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
--(3)創建一個觸發器,刪除一個部門的時候,判斷該部門下是否有員工,有則不刪除,沒有則刪除
drop trigger tri_DeleteDept--刪除觸發器
create trigger tri_DeleteDept on Department instead of delete
as
--if exists(select * from People where DepartmentId = 將要刪除的部門編號)
--部門不存在員工,才要刪除部門,if exists 可以改成 if not exists
if not exists(select * from People where DepartmentId = (select DepartmentId from deleted))
delete from Department where DepartmentId = (select DepartmentId from deleted)
go
--測試觸發器
--測試一:部門下沒有員工的
delete from Departmentt where DepartmentId = '005'
--測試二:部門下有員工的
delete from Departmentt where DepartmentId = '001'
範例4:after update-修改一個部門編號之後,同步修改該部門下員工資料
after update修改後進行觸發- 修改什麼?
1 2
update People set DepartmentId = 新編號 --新增的編號(inserted table) where DepartmentId = 原來的老編號 --刪掉的編號(deleted table)
實作
1
2
3
4
5
6
7
8
9
10
--(4)修改一個部門編號之後,將該部門下所有員工的部門編號同步進行修改
create trigger tri_UpdateDept on Department after update
as
--update People set DepartmentId = 新編號(inserted table)
--where DepartmentId = 原來的老編號(deleted table)
update People set DepartmentId = (select DepartmentId from inserted)
where DepartmentId = (select DepartmentId from deleted)
go
--測試觸發器
update Department set DepartmentId = '005' where DepartmentId = '001'
Triiger 的 inserted Table & deleted Table
deleted Table和 inserted Table 為 Triiger 使用的兩個特殊暫存資料表(交易紀錄的檢視表),其欄位名稱、順序和資料型態都跟原來的 Table 一致,可以利用它們了解 INSERT、UPDATE 和 DELETE T-SQL 語法觸發 Triiger 時,插入、修改或是刪除哪些資料。
inserted Table會儲存INSERT和UPDATE前的資料deleted Table則會儲存UPDATE後和DELETE的資料。
MSDN 使用 inserted 與 deleted 資料表
[SQL] Trigger - inserted & deleted Table
https://www.bilibili.com/video/BV1XV411C7TP?p=29