级联删除的触发器代码解释

级联删除的触发器代码解释 这个是比较复杂的T-SQL代码了。
    作用:级联删除,如果要删除主类别表的记录,那么把次类别表所属记录以及这个类别所包含的所有文章内容删除。 

    主类别表名:Navtion_TopSubject 主键fTopID Char(36)
    次类别表名:Navtion_NodeSubject 外键同上
    内容表名:tText 外键同上
   
    代码如下:
   
    //---------代码开始------------------------------------------------
   
    CREATE TRIGGER [RemoveTopAndNodeText] ON [dbo].[Navtion_TopSubject]
    INSTEAD OF DELETE
    AS
   
    /* 定义触发器使用的变量 */
    DECLARE
    @fTopID Char(36),
    @fNodeCount Int,
    @fTextCount Int,
    @fTopName VarChar
   
   
    /* 把传送的需要删除的fTopID键值赋值给@fTopID变量 */
    /* 开始事务 */
    BEGIN TRAN Remove_TopSubject
    Set @fTopID = (Select fTopID From deleted)
    Set @fTopName = (Select fTopName From deleted)
   
    /* 保存删除前保存点,防止出错 */
    Save Tran my_Save1
   
    /* 首先判断子类表NodeSubject中是否有所属内容 */
    Set @fNodeCount = (Select Count(*) From Navtion_NodeSubject Where Navtion_NodeSubject.fTopID = @fTopID)
    If @fNodeCount > 0
    Begin
    /* 判断内容表tText是否有所属内容 */
    Set @fTextCount = (Select Count(*) From tText Where tText.fTopID = @fTopID)
    If @fTextCount > 0
    Begin
    Delete From tText Where tText.fTopID = @fTopID
    Delete From Navtion_NodeSubject Where fTopID = @fTopID
    Delete From Navtion_TopSubject Where fTopID = @fTopID
    End
    Else
    Begin
    Delete From Navtion_NodeSubject Where fTopID = @fTopID
    Delete From Navtion_TopSubject Where fTopID = @fTopID
    End
    End
    Else
    Begin
    Delete From Navtion_TopSubject Where fTopID = @fTopID
    End
   
    If @@Error = 0
    Commit Transaction
    Else
    Begin
    Rollback Transaction my_Save1
    Raiserror('删除出现错误,记录:%s及其所属内容没有被删除。',16,1,@fTopName)
    End
   
    //------------------代码结束---------------------
   
    现在我把这个触发器代码详细解释一下:
    一、背景
    这是我写的一个文章处理系统,分类级别为两级,就是说有两级目录类似这种:
    新闻
    -->国内新闻
    -->国际新闻
    教程
    -->ASP教程
    -->C#教程
    -->JSP教程
    下载
    -->工具下载
    -->源代码下载
    每个文章都属于上面的目录下的一个。
    这样看,数据库内必须有三个表:主类别表、次类别表、文章内容表。而且,我为了保证数据的完整性,使用了关系(懂SQL Server的知道),这样,假设新闻类下有子类并且每个子类下有文章的话,使用Deltee语句删除类将出现错误,因为违反了数据完整性约束,把类别删除后所属的记录将变为死记录。所以删除主表的记录必须保证这个类别所包含的子类别和内容全部删除。我写的这个触发器的作用就是删除主表类别的触发器,可以在主表类别下有内容的情况下删除主表的记录。
   
    二、数据库结构
    1.主类别表
    表名:Navtion_TopSubject
    主健:fTopID 数据类型:Char 大小:36
    类别名: fTopName 数据类型:VarChar 大小:30
    2. 次类别表
    表名:Navtion_NodeSubject
    主键:fNodeID 数据类型:Char 大小:36
    外键:fTopID 数据类型:Char 大小:36 (表示此记录所属的主类别)
    类别名:fNodeName 数据类型:VarChar 大小:30
    3. 内容表:
    表名:tText
    主键:fID 数据类型:Char 大小:36
    外键1:fTopID 指向主类别表 表示所属的主类别
    外键2:fNodeID 指向次类别表,表示所属的次类别
   
    三、操作流程
    1. 这个触发器放在主类别表Navtion_TopSubject中,触发条件是Delete语句,如果对这个表执行了删除命令的话,那么将触发此代码的运行。
    2. 定义触发器接受传递过来的Delete语句,然后根据这个语句来执行代码。
    3. 标准SQL删除代码如下:
    DELETE From Navtion_TopSubject Where fYopID = 'aaa' (假设要删除的主类别是新闻,主键编号是aaa)
    4. 这样我们就可以利用这个aaa来查找次类别表和内容表是否有所属的内容。
    5. 利用deleted表,这个表是逻辑删除表,相当于Windows系统里面的回收站。Sql Server系统定义:如果一个表里面有触发器,那么任何操作都不直接进行,而是进行逻辑操作。这个操作在Inserted表(插入),Updated表(更新),Deleted表(删除)中进行。就拿Deleted表来说,传递到Sql Server系统中的Del命令,如果有触发器的话,Sql首先复制这个要删除的记录到Deleted表中(这个表是个临时表,只能给触发器用,触发器运行结束后自动删除),我们就可以用此代码:
    Select fTopID From deleted
    获得传递到Sql的表Navtion_TopSubject中记录为aaa的主键内容。
    6. 把这个主键内容存放到变量中,根据这个变量找次类别表,如果没有内容,表示此记录没有任何次类别和文章,可以直接删除。
    7. 如果次类别表中有内容,那么再用这个变量找内容表中属于aaa的内容,如果有,就删除,再删除次类别表的内容,如果没有,则直接删除次类别表的内容。
    8. 当次类别表和内容表的记录全部删除干净后,删除主类别表的内容。
   
    四、流程定义
    先查找子类别的数量,赋值给@NodeCount变量,然后判断
   
    如果>0
   
    则根据@fTopID找tText表的内容赋值给@fTextCount,如果>0则
    首先删除tText表符合@fTopID内容的所有记录
    然后删除子类别表Navtion_NodeSubject表中符合@fTopID的所有内容
    最后删除主类别表Navtion_TopSubject中符合@fTopID的所有内容
    否则
    首先删除Navtion_NodeSubject子类别表中符合@fTopID的所有内容
    然后删除主类别表Navtion_TopSubject中符合@fTopID的所有内容
   
    否则
    仅删除主类别表Navtion_TopSubject中符合@fTopID的所有内容
   
    五、代码解释
   
    CREATE TRIGGER [RemoveTopAndNodeText] ON [dbo].[Navtion_TopSubject]
    INSTEAD OF DELETE
    AS
   
    上面的代码是建立触发器的Sql语句,内容:
    CREATE TRIGGER T-SQL关键字,表示是一个触发器
    [RemoveTopAndNodeText] 是触发器的名称
    [dbo].[Navtion_TopSubject] 表示这个触发器属于的表的名称
    INSTEAD OF 表示这个触发器将屏蔽传递进来的Sql命令,转向执行触发器的

posted @ 2008-12-22 11:10  小麻雀  阅读(776)  评论(0)    收藏  举报