SQL Server 2005嵌套触发器
发布时间:2021-01-10 03:16:18 所属栏目:MySql教程 来源:网络整理
导读:今天PHP站长网 52php.cn把收集自互联网的代码分享给大家,仅供参考。 如果一个触发器在执行操作时引发了另一个触发器,而这个触发器又接着引发下一个触发器……这些触发器就是嵌套触发器。触发器可嵌套至 32 层,并且可以
以下代码由PHP站长网 52php.cn收集自互联网 现在PHP站长网小编把它分享给大家,仅供参考 如果一个触发器在执行操作时引发了另一个触发器,而这个触发器又接着引发下一个触发器……这些触发器就是嵌套触发器。触发器可嵌套至 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',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 以上内容由PHP站长网【52php.cn】收集整理供大家参考研究 如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。 (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |