當我們想更新一張動態表的時候(即:表中的資料不斷的添加),也許我們會用資料庫代理,通過寫作業,然後讓他定時查詢動態表中最新添加的資料,然後更新資料。這樣時能實現更新資料的要求,但是資料卻不能即時同步更新。
這個時候,觸發器就是我們想要的神器了。我們可以在那張動態表上建立觸發器。觸發器的實質就是個預存程序,只不過他調用的時間是根據所建的動態表發生該表而執行(即:Insert新資料,Update或者Delete資料)。
具體怎麼使用觸發器,今天我這裡就不介紹了,園子裡資料多的很。那麼我今天要介紹的是什麼呢?
前幾天在寫sql代碼的時候無意間發現了這麼個問題:就是我一直以為每當動態表中插入一條資料,觸發器就執行一次,但是我這樣理解的話,當批量插入資料的時候,觸發器執行的次數和插入的行數相同,但是事實不是這樣。乘著今天有點時間,就想寫出來和大家分享下,講的不對請大家斧正!
下面,我就寫了個簡單的例子供大家參考。 複製代碼 代碼如下:--我們要建觸發器的動態表
Create table Table_a
(
ID int identity(1,1),--自增ID
Content nvarchar(50),
UpdateIDForTrigger int
)
然後我們在該表上建立一個觸發器 複製代碼 代碼如下:Create TRIGGER [dbo].[Table_a_Ins]
ON [dbo].[Table_a]
AFTER INSERT
AS
BEGIN
declare @ID int
set @ID=(select ID from inserted)
--更新Table_a表中的UpdateIDForTrigger欄位的值,為了能更明顯的看出即時執行的效果
UPDATE Table_a
SET UpdateIDForTrigger = (@ID+10)--為了能看出不同,就直接將比ID大10的值作為變數賦值
WHERE ID = @ID;
END
接下來,我們按照普通一條條的插入結果測試下: 複製代碼 代碼如下:--給資訊表添加資料
insert into Table_a(Content) values('資訊一');
insert into Table_a(Content) values('資訊二');
然後查詢下現在動態表中的資料情況 複製代碼 代碼如下:select * from Table_a
查詢結果
我們可以看到觸發器執行了。在每條資料插入的時候觸發器同時執行了Update功能。
然後,我們要批量插入資料,為了方便我們插入,我們這裡建立一張臨時的基本資料表: 複製代碼 代碼如下:--基本資料表
Create table Table_Info
(
ID int identity(1,1),
Content nvarchar(50)
)
然後插入資料 複製代碼 代碼如下:insert into Table_Info(Content) values('資訊三');
insert into Table_Info(Content) values('資訊四');
insert into Table_Info(Content) values('資訊五');
insert into Table_Info(Content) values('資訊六');
insert into Table_Info(Content) values('資訊七');
insert into Table_Info(Content) values('資訊八');
insert into Table_Info(Content) values('資訊九');
insert into Table_Info(Content) values('資訊十');
然後我們就可以批量插入資料到動態表中了 複製代碼 代碼如下:insert into Table_a(Content)
select Content from Table_Info
這次重點來了,我們在執行這個sql語句的時候訊息框中會出現錯誤提示:
有經驗的朋友會知道,這個錯誤是由於多個結果用“=”賦值給一個變數導致的。
即:set @變數=(select 多行結果 from Table)
這個時候,我就疑惑了,問題出在哪裡了呢?不是觸發器在每插一條資料的時候執行一次嗎?
於是,我將觸發器改了下: 複製代碼 代碼如下:Alter TRIGGER [dbo].[Table_a_Ins]
ON [dbo].[Table_a]
AFTER INSERT
AS
BEGIN
select ID from inserted;
END
然後再執行上面的批量插入試試看,看看他inserted表中到底存的是什麼值:
果然不出所料,inserted表中的結果並不是一條資料:
知道錯誤的原因,我們操作起來就簡單了,我們可以給inserted表建遊標,然後通過遊標來對批量插入的每行資料進行編輯。下面是我們修改後的觸發器代碼: 複製代碼 代碼如下:Alter TRIGGER [dbo].[Table_a_Ins]
ON [dbo].[Table_a]
AFTER INSERT
AS
BEGIN
declare @ID int
declare cur_Insert cursor
for
select ID from inserted
open cur_Insert
fetch next from cur_Insert into @ID
while @@fetch_status=0
begin
UPDATE Table_a
SET UpdateIDForTrigger = (@ID+10)--為了能看出不同,就直接將比ID大10的值作為變數賦值
WHERE ID = @ID;
fetch next from cur_Insert into @ID
end
close cur_Insert
deallocate cur_Insert
END
然後,我們再按照上面的批量插入資料,然後查詢下動態表中的結果: 複製代碼 代碼如下:insert into Table_a(Content)
select Content from Table_Info;
select * from Table_a;
此時運行沒有錯誤提示了,運行結果如下:
這樣,批量插入插入資料時觸發器也能用了。
然後結合了幾位前輩的建議,再改了下觸發器的代碼。將上面的遊標改成了下面的方式:
複製代碼 代碼如下:Alter TRIGGER [dbo].[Table_a_Ins]
ON [dbo].[Table_a]
AFTER INSERT
AS
BEGIN
UPDATE Table_a
SET UpdateIDForTrigger =inserted.ID+10
FROM inserted
Where Table_a.ID=inserted.ID
END
然後再批量插入了幾行資料,結果也是可以的。所以學無止境啊!!
總結下:觸發器運行是每次執行一次Insert操作或者是Update,Delete等操作的時候才執行的。它的對象不是針對於修改的行數(即:每行修改的時候執行)。