Sybase触发器更进一步

ZDNet软件频道 时间:2002-06-11 作者:BUILDER.COM |  我要评论()
本文关键词:sybase
本文是sybase数据库触发器系列文章的第二篇,我希望读者能认识到触发器是数据库综合设计的重要组成部分。

上一篇文章里,我们讨论了sybase 触发器的设计及其最基础的主要相关知识。下面我们就继续介绍更深入些的触发器技术主题。我们将在这篇文章中讨论递归/嵌套触发器以及其他若干种数据库设置。本文是sybase数据库触发器系列文章的第二篇,我希望读者能认识到触发器是数据库综合设计的重要组成部分。

嵌套触发器

如果某数据表上的触发器对另一数据表执行DML(数据修改语言)语句操作,而后一数据表上又有一个触发器正好响应DML操作(INSERT、UPDATE或者DELETE),那么第2个触发器也会被触发。这就是所谓的触发器“嵌套”,其嵌套层次可以达到16级。嵌套层次源自触发器内的@@ nestlevel变量。嵌套触发器的功能可以通过Allow Nested Triggers配置参数打开或者关闭。

如果触发器调用了存储过程,而该存储过程又对同一表实施DML语句操作而且数据库启用了递归触发器配置,那么以上行为将可能导致嵌套层次突破限制而进入无限循环以至于触发器失败。递归触发器将在下一节讨论。

如果嵌套触发器中(或第一个触发器)出现回滚触发器,那么所有被第1个触发器(也就是最初的DML语句响应者)所调用的触发器都被回滚。回滚事务将把所有操作全部回滚到事务以外的状态。

嵌套触发器和/或存储过程的嵌套层次可以通过访问@@ nestlevel全局变量得以确定。触发器和存储过程可以互相调用,而且都能影响@@ nestlevel变量值。

递归触发器

如果触发器对自己所在的表执行DML语句操作或调用存储过程乃至触发另一完成以上操作的触发器,那么以上连续过程的头一个触发器可能重新被触发。这就是所谓的“嵌套”,在缺省状态下这种嵌套行为在sybase数据库中是被关闭的。然而,系统管理员(SA)可以通过Allow Nested Triggers配置选项的设置启用嵌套触发器。

偶然地引起自我递归也不是件容易的事。你不仅得要求SA配置Allow Nested Triggers选项而且还得设置Self_Recursion On选项。如果这一选择设置在某一触发器之外,那么设置在客户会话的整个持续时间内有效。如果触发器调用其他触发器,Self_Recursion选项将再次默认为关闭。当设置该选项的触发器结束操作时,该选项回复到默认设置。

插入表和删除表

在上一篇文章里我们提到了插入表和删除表。现在我们更深入地讨论下这两种特殊的数据表。在触发器的执行期间,插入表和删除表可通过事务日志得到。它们没有自己的属主而且只需要由其名称“inserted”和“deleted”所指定。

程序清单A 就是插入触发器的示例,该程序的作用是保证外键具有正确的主键匹配。Discounts表把stor_id作为其外键并把它映射到stores表的主键。

在上面的例子中我们根据stores表的stor_id主键给discounts表和stores表内的现有的记录建立了连接(join)。如果我们没有得到等于插入记录数目的匹配值(就像@@ rowcount全局变量一样),那么我们就知道插入表中的stor_id值至少有一个在stores表没有对应值。为了保证引用的完整性,我们随后取消了全部事务,把所有的修改操作都回滚到了事务以外的开始状态。

你可以注意到我们核对了@@ rowcount != 0 因此在实际上没有插入数据行的情况下我们可以避免触发器余下操作所带来的计算负荷。这主要发生在以下情况中:执行多行插入的时候没有一行数据能满足WHERE子句的条件。

你可能还注意到我们把@@ rowcount的值赋给了触发器的一个条目变量。我们已经知道,@@ rowcount全局变量只为最后的SQL语句保存了受到影响的数据行的数目值而且会被除DECLEAR语句之外的其他所有SQL语句复位。因此,如果你希望可靠地在存储过程或触发器中使用它,你应该总是在进入触发器之上立刻把它的值赋给一个变量。

前面的那个限制插入操作的例子也可以应用在以下删除主键的场合,此时该主键匹配的外键存在于其他表中。

以下是级联删除的示例。注意在执行级联删除操作的时候务必小心。有时出于历史记录的目的,我们希望能在执行DELETE语句之前保证外键表的数据行都被归档。触发器可以实现以上的目标,但这是针对高级用户的操作了而且也超出了本文所讨论的主题范围。

程序清单B中所示为触发器的“级联删除”功能。在这种情况下你或许打算把删除的记录保存在historical表内。要实现这一目标可以给数据表的删除增加一个触发器,然后把删除表内的记录插入到historical表,如程序清单C所示。

注意,程序清单C中的最后一列:deleted_by 并不存在于基表中,但这正是归档表中所希望的,由此可以用来追踪实际上执行删除的人。这是审核操作的常用方法,尤其是针对数据的删除操作。

其他限制

在我写的上一篇文章《用sybase触发器保护你的数据》里,我大致提出了一些基本的触发器用途限制条件。下面是你你应该注意的其他限制:

  • 不要在系统表上创建触发器。
  • 在触发器内不要访问产插入表或者删除表上文本或图象列。
  • 如果你正在使用Component Integration Services服务,则代理表上的触发器不能访问插入表或者删除表,原因是这类表所在的事务日志位于远程服务器上。
小结

到现在为止,我们已经讨论了涵盖触发器设计和开发的大多数基础知识。在我们的下一篇文章里将仔细研究如何保证总结表内的派生值同原始细节表保持同步的问题。我们还将讨论基表中的多行主键更新以及如何修改关系表内的外键引用。

责任编辑:炒饭

欢迎评论或投稿


百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134