国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > SQL Server > 正文

SQL SERVER使用嵌套觸發器

2024-08-31 00:49:27
字體:
來源:轉載
供稿:網友
,歡迎訪問網頁設計愛好者web開發。如果一個觸發器在執行操作時引發了另一個觸發器,而這個觸發器又接著引發下一個觸發器……這些觸發器就是嵌套觸發器。觸發器可嵌套至 32 層,并且可以控制是否可以通過"嵌套觸發器"服務器配置選項進行觸發器嵌套。

如果允許使用嵌套觸發器,且鏈中的一個觸發器開始一個無限循環,則超出嵌套級,而且觸發器將終止。

可使用嵌套觸發器執行一些有用的日常工作,如保存前一觸發器所影響行的一個備份。例如,可以在 titleauthor 上創建一個觸發器,以保存由 delcascadetrig 觸發器所刪除的 titleauthor 行的備份。在使用 delcascadetrig 時,從 titles 中刪除title_id ps2091 將刪除 titleauthor 中相應的一行或多行。要保存數據,可在 titleauthor 上創建 delete 觸發器,該觸發器的作用是將被刪除的數據保存到另一個單獨創建的名為 del_save 表中。例如:

create trigger savedel
   on titleauthor
for delete
as
   insert del_save
   select * from deleted

不推薦按依賴于順序的序列使用嵌套觸發器。應使用單獨的觸發器層疊數據修改。


說明  由于觸發器在事務中執行,如果在一系列嵌套觸發器的任意層中發生錯誤,則整個事務都將取消,且所有的數據修改都將回滾。在觸發器中包含 print 語句,用以確定錯誤發生的位置。


遞歸觸發器
觸發器不會以遞歸方式自行調用,除非設置了 recursive_triggers 數據庫選項。有兩種不同的遞歸方式: 

直接遞歸 
即觸發器激發并執行一個操作,而該操作又使同一個觸發器再次激發。例如,一應用程序更新了表 t3,從而引發觸發器 trig3。trig3 再次更新表 t3,使觸發器 trig3 再次被引發。

間接遞歸 
即觸發器激發并執行一個操作,而該操作又使另一個表中的某個觸發器激發。第二個觸發器使原始表得到更新,從而再次引發第一個觸發器。例如,一應用程序更新了表 t1,并引發觸發器 trig1。trig1 更新表 t2,從而使觸發器 trig2 被引發。trig2 轉而更新表 t1,從而使 trig1 再次被引發。

當將 recursive_triggers 數據庫選項設置為 off 時,僅防止直接遞歸。若要也禁用間接遞歸,請將 nested triggers 服務器選項設置為 0。

示例
a. 使用遞歸觸發器解決自引用關系

遞歸觸發器的一種用法是用于帶有自引用關系的表(亦稱為傳遞閉包)。例如,表 emp_mgr 定義了: 

一個公司的雇員 (emp)。


每個雇員的經理 (mgr)。


組織樹中向每個經理匯報的雇員總數 (noofreports)。 
遞歸 update 觸發器在插入新雇員記錄的情況下可以使 noofreports 列保持最新。insert 觸發器更新經理記錄的 noofreports 列,而該操作遞歸更新管理層向上其它記錄的 noofreports 列。

use pubs
go
-- turn recursive triggers on in the database.
alter database pubs
   set recursive_triggers on
go
create table emp_mgr (
   emp char(30) primary key,
    mgr char(30) null foreign key references emp_mgr(emp),
    noofreports int default 0
)
go
create trigger emp_mgrins on emp_mgr
for insert
as
declare @e char(30), @m char(30)
declare c1 cursor for
   select emp_mgr.emp
   from   emp_mgr, inserted
   where emp_mgr.emp = inserted.mgr

open c1
fetch next from c1 into @e
while @@fetch_status = 0
begin
   update emp_mgr
   set emp_mgr.noofreports = emp_mgr.noofreports + 1 -- add 1 for newly
   where emp_mgr.emp = @e                            -- added employee.

   fetch next from c1 into @e
end
close c1
deallocate c1
go
-- this recursive update trigger works assuming:
--   1. only singleton updates on emp_mgr.
--   2. no inserts in the middle of the org tree.
create trigger emp_mgrupd on emp_mgr for update
as
if update (mgr)
begin
   update emp_mgr
   set emp_mgr.noofreports = emp_mgr.noofreports + 1 -- increment mgr's
   from inserted                            -- (no. of reports) by
   where emp_mgr.emp = inserted.mgr         -- 1 for the new report.

   update emp_mgr
   set emp_mgr.noofreports = emp_mgr.noofreports - 1 -- decrement mgr's
   from deleted                             -- (no. of reports) by 1
   where emp_mgr.emp = deleted.mgr          -- for the new report.
end
go
-- insert some test data rows.
insert emp_mgr(emp, mgr) values ('harry', null)
insert emp_mgr(emp, mgr) values ('alice', 'harry')
insert emp_mgr(emp, mgr) values ('paul', 'alice')
insert emp_mgr(emp, mgr) values ('joe', 'alice')
insert emp_mgr(emp, mgr) values ('dave', 'joe')
go
select * from emp_mgr
go
-- change dave's manager from joe to harry
update emp_mgr set mgr = 'harry'
where emp = 'dave'
go
select * from emp_mgr
go

以下是更新前的結果:

emp                            mgr                           noofreports
------------------------------ ----------------------------- -----------
alice                          harry                          2
dave                           joe                            0
harry                          null                           1
joe                            alice                          1
paul                           alice                          0

以下為更新后的結果:

emp                            mgr                           noofreports
------------------------------ ----------------------------- -----------
alice                          harry                          2
dave                           harry                          0
harry                          null                           2
joe                            alice                          0
paul                           alice                          0

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 许昌市| 宁德市| 富源县| 衢州市| 嘉黎县| 昌邑市| 庆元县| 苏尼特左旗| 双桥区| 当阳市| 长白| 通山县| 龙州县| 沂水县| 海原县| 德江县| 天等县| 平武县| 岳池县| 资溪县| 屏东市| 英超| 自贡市| 石城县| 二连浩特市| 灵武市| 醴陵市| 临潭县| 宁波市| 运城市| 宝丰县| 灵川县| 茂名市| 漯河市| 额尔古纳市| 荔浦县| 合肥市| 兴隆县| 卓尼县| 克东县| 临邑县|