zoukankan      html  css  js  c++  java
  • 关于触发器的若干收获

    最近在做一个权限管理的模块,原本设计的数据库表之间有大量的外键关系,而这些外键之间的结构是非树状的,所以使用ms sql来建立数据库中总要报错。最后决定用触发器来代替外键,基本思想就是在原本需要用外键的地方,在主键表上建立after update和after delete的触发器。
         下面是一些例子
          表Menu1中有列Name,而表Menu2中列Father,原本前者是后者的外键,现在用触发器代替。 
         after update触发器
         If exists(select * from sysobjects where id=object_id(N'[dbo].[triggertest ]') and objectproperty(id,N'istrigger')=1)
         DROP TRIGGER triggertest 
         go
         create trigger triggertest on Menu1
         after update
         as
         if update(Name)
         begin
           update Menu2 set Father = (select Name from inserted)
          where Father = (select Name from deleted)
        end

          after delete触发器
          If exists(select * from sysobjects where id=object_id(N'[dbo].[triggertest2 ]') and objectproperty(id,N'istrigger')=1)
          DROP TRIGGER triggertest2 
         go
         create trigger triggertest2 on Menu1
         after delete
         as
         if (select count(*) from deleted ) > 0
         begin
           delete from Menu2 where Father = (select Name from deleted)
        end

    其中语句
    If exists(select * from sysobjects where id=object_id(N'[dbo].[XXX ]') and objectproperty(id,N'istrigger')=1)
          DROP TRIGGER XXX
    用于判断触发器XXX 是否已经存在,若存在将其从库中剔除。

    语句  if update(XX)是判断表中的XX列是否有被更新,当我们对表中XX列执行update ... set ....操作或insert操作时,update(XX)为真。在这里我们还有另一种方式来判定某列是否被更新,那就是使用
    IF (COLUMNS_UPDATED())语句,它用语测试是否插入或更新了提及的列,仅用于 INSERT 或 UPDATE 触发器中。COLUMNS_UPDATED 返回 varbinary 位模式,表示插入或更新了表中的哪些列。CLUMNS_UPDATED 函数以从左到右的顺序返回位,若表中中有5列,分别为C1,C2,C3,C4,C5,其中C1,C2,C5被更新的话,那么它将返回10011,依此类推。在 INSERT 操作中 COLUMNS_UPDATED 将对所有列返回 TRUE 值,因为这些列插入了显式值或隐性 (NULL) 值。如果需要判断表中某些列是否被更新,则需要用到updated-bitmask即整型掩码,对于刚才提到的拥有5列的那个表,如果我们想知道C1有没有被更新,那么只要用if (COLUMNS_UPDATED() & 1) 就可以啦。若要判断C1,C4有是否有被更新,则用9(1001)代替1就可以啦。
     语句 if (select count(*) from deleted ) > 0 用于判断表deleted是否为空,我们还有许多办法来判断表是否为空
        select  *  from  test  
        if  @@rowcount  >0  

    -------------------------------------------------------------  

      if  exists  (select  *  from  test)  

    ---------------------------------------------------------------  

     if  (select  top  1  id  from  test)  is  null    

      使用这个语句的目的在于防止触发器的间接或直接递归。比如说在表p1中,我们建立after update触发器,在触发的事件中我们delete表p2的某个符合id > 0的行,然后在表p2中,我们建立after delete触发器,在触发事件中,我们update表p2。那么如果没有加上如上的判断表是否为空的语句,那么将会出现“触发器超过最大允许嵌套次数”的错误。 

  • 相关阅读:
    站点防攻击之禁止国外ip
    docker 安装rabbitMQ
    【转】浅析支付系统的整体架构
    【转】MQ详解及四大MQ比较
    SQL server 中的dbo、guest
    网站加载速度的优化(1):优化前端页面
    【转】Apache ab压力测试
    Asp.Net Core 部署发布后EFCore数据库断连和Google浏览器无法存储Cookie
    C# 使用nuget.exe发布类库及更新类库
    .net core 读取Excal文件数据及注意事项
  • 原文地址:https://www.cnblogs.com/ost/p/478832.html
Copyright © 2011-2022 走看看