分享

SYBASE触发器及应用

 king9413 2007-05-08

SYBASE触发器及应用

杨基镇

Application of Sybase Trigger

Yang Jizhen

1 触发器的创建方法
  一般地,创建触发器的语法如下:
  Create Trigger触发器名称
  On 表名&&指定所创建的触发器与某个已存在的表关联。
  For {Insert, Delete, Update}&&指定触发器的类型(即插入,删除,更新或它们的任意组合)
  As
  SQL语句&&指定触发器的触发条件或动作
  “触发器名称”的格式如trg-[d][i][u]-xxxxx,其中d表示一个删除类型的触发器,i表示一个插入类型的触发器,u表示一个更新类型的触发器,xxxxx表示触发器所作用的表的名称。
  触发器与触发它的SQL语句是作为同一个事件来执行的,因而这里的“SQL语句”不能是任意的SQL语句。如果有多个对同一个表进行同一类型操作的触发器,那么新的触发器将会自动替代旧的触发器。一个触发器只能用于一个表,而一个表可以有最多三个触发器。只能在当前的数据库中创建触发器,而且对于临时表或者视图不能创建触发器。

2 触发器的作用
  1. 实现复杂的数据完整性约束,即主键外键参照完整性。这就是说,不能在主表中删除或更新正在被相应从表的外键参照的主键值,如果一定要在主表中删除或更新,不能在从表中插入或更新在相应主表的主键列中不存在的外键值;如果一定要在从表中插入或更新,那么相应主表的主键列中不存在的外键值,如果一定要在从表中插入或更新,那么相应主表也必须跟着作相应的插入或更新。
  2. 维护复制数据的一致性。复制数据将是动态的、实时的数据。
  3. 自动刷新导出数据。在表中的记录发生变化时,希望其导出数据也能跟随着发生变化,利用触发器就可以自动地刷新导出数据。
  4. 施加特殊的业务规则和行为限制。不同的行业会有不同的业务规则和行为限制,利用触发器可以轻松地规范具体的业务和复杂的行为。这是触发器的一大具体作用。
  5. 监控某些特定行为的发生。利用触发器可以拒绝执行非法行为并将发出非法行为的操作者和操作时间记录下来,便于安全管理。

3 触发器的工作原理
  对于每个触发器,SQL Server都会自动创建2个临时工作表,即inserted表和deleted表,这2个表作为系统的专用表存放于内存中,其结构与被作用的表相同,且在触发行为结束后自动被删除。
  表1分别说明inserted和deleted这二个工作表与客户端发出的Insert,Delete或Update请求的关系。
表1

客户请求 SQL Server响应 工作表名称 工作表内容
Insert 插入新行 inserted 被插入的行
deleted /
Delete 删除旧行 inserted /
deleted 被删除的行
Update 插入新行、删除旧行 inserted 被插入的行
deleted 被删除的行
  在触发器的工作过程中,系统提供了一个行计数的全局变量@@rowcount,它有着非常重要的作用。
  首先,通过它可以知道表中受某个操作影响的行数,这样可以避免不必要的操作。如果某个表已经建立触发器,那么在进行Insert,Delete或Update的操作时,可以通过全局变量@@rowcount了解表中的行是否受影响,有多少行受影响,因为它记录了受影响的行数。
  其次,通过它可以实现对表插入或更新操作的主键外键参照完整性。可以将inserted表与相应的主表在主键列上进行连接操作所得到的行数跟进入触发器的全局变量@@rowcount进行比较,如果相等,表明对从表插入或更新操作的外键新值在主表的主键列中已经存在,允许对从表操作;否则,要么不允许对从表操作,要么作其他处理。

4 触发器的应用实例
  我们先作一个约定:假设现在有一个主表Base(id,name)和一个从表Sales(id,account),Base中的id为主键,那么Sales中的id为外键。下面举例说明上述的3种触发器。
4.1 Delete触发器
  现在准备删除主表Base中的一行,由于Base是主表,所以希望能把从表Sales中的相关记录一起删去,以保持参照完整性,为此,创建Delete触发器如下:
  create trigger trg-d-base
    on base for delete
  as
  if @@rowcount=0
    return
  delete sales from sales s, deleted d
    where s. id=d.id
  return
4.2 Insert触发器
  现在准备在从表ales中插入一行,希望检查新的id是否合法,即是否在主表Base的主键列中存在,以保持参照完整性,为此,创建Insert触发器如下:
  create trigger trg-iu-sales
    on sales for insert, update
  as
  declare @n-row int
  select @n-row=@@rowcount
  if @n-row=0
    return
  if (select count(*) from base b, inserted i
  where b.id=i.id)!=@n-row
  begin
    raiserror 31113“不能插入在主表中不存在的外键。”
    rollback transaction
    return
  end
  return
4.3 Update触发器
  现在准备更新主表Base中的一个id,由于Base是主表,所以希望能把从表Sales中的相关记录的id一起更新,以保持参照完整性,为此,创建Update触发器如下:
  create trigger trg-u-base
    on base for update
  as
  declare @n-row int
  select @n-row=@@rowcount
  if @n-row=0
    return
  if update(id)
  begin
  if @n-row>1
  begin
    raiserror 31113“不能把多个主键更新成同一个值。”
    rollback transaction
    return
  end
  update sales set s.id=i.id
    from sales s, inserted i, deleted d
    where s. id=d.id
  end
  return

作者单位:杨基镇 广东省汕头市国土房产局产权科工程师(515041)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多