// ------------- 代码开始 -------------------- 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 //------------------代码结束---------------------
/* 保存删除前保存点,防止出错 */ Save Tran my_Save1 以上代码解释: 放在 /* 和 */之间的是程序注释,类似于Html里面的<!-- 和--> BEGIN TRAN Remove_TopSubject 表示开始事务,其中RemoveTopSubject是事务名称。 事务就是保证操作成功的一种机制,如果在事务里面出错,那么事务将回滚,不会影响整个系统。 举个例子,如果在事务里面定义了3个操作a b c,分别是a 插入一条记录,b 删除一条记录,c 更新一条记录。程序开始执行,如果a 执行成功后开始操作b,b操作出现错误,那么事务开始回滚,插入记录的a将会取消,返回到没有执行这3个操作之前的状态。 Set @fTopID = (Select fTopID From deleted) 这个是Sql Server的赋值命令,把变量@fTopID的值保存成deleted表中fTopID字段的内容。 Set @fTopName = (Select fTopName From deleted) 同样的赋值命令,把要删除的主类别的名称赋值给@fTopName变量,在后面的出错语句用。 Save Tran my_Save1 Save Tran表示保存事务,如果发生错误,则可以用这个保存来恢复。类似于游戏里面的存盘文件。my_Save1是保存名,相当于存盘文件名。 接上: Set @fNodeCount = (Select Count(*) From Navtion_NodeSubject Where Navtion_NodeSubject.fTopID = @fTopID) 也是一个变量赋值语句,设定@fNodeCount变量保存的是要删除的主表记录(@fTopID变量的内容)所属的次类别表Navtion_NodeSubject中的记录的数量 根据主表记录查找其他表符合条件的这个语句可参考这个帖子: http://www.dw-mx.com/forum/mb_forum/detail2.asp?f2_id=37&f3_id=9022&f3_name=笑望人生 -------------------------------------------------------------------- If @fNodeCount > 0(作个标记,一级判断) 开始判断,如果@fNodeCount大于0,表示欲删除的主类别记录包含有子类别,不能直接删除,必须先删除子类别。 但删除子类别必须删除子类别下包含的所有内容(文章)记录,所以我们必须判断是否有内容记录 ----------------------------------------------------------------- Begin (作个标记,一级Begin) 表示If下面执行的多条语句,不懂的可以参考没人性的FAQ帖子 -------------------------------------------------------------- Set @fTextCount = (Select Count(*) From tText Where tText.fTopID = @fTopID) 上面代码继续赋值,@TextCount表示欲删除的主类别记录所包含的所有的内容(文章)记录的数量 ------------------------------------------ If @fTextCount > 0(标记,二级判断) 判断记录的数量,大于0表示有记录,这样必须先删除内容表的记录,再删除子类别表的记录,最后删除主类别表的记录,这样才不会出错。 Begin (标记 ,二级Beging 一) --------------------------------------------------- Delete From tText Where tText.fTopID = @fTopID Delete From Navtion_NodeSubject Where fTopID = @fTopID Delete From Navtion_TopSubject Where fTopID = @fTopID End(标记,二级Begin一的结束命令) 上面的语句很简单,首先删除tText表中fTopID符合@fTopID的记录(删除内容表) 然后删除Navtion_NodeSubject表符合@fTopID的记录(删除次类别表) 最后删除Navtion_TopSubject表符合@fTopID的记录(删除主类别表) ---------------------------------------------------- Else (标记,二级判断否则,表示@fTextCount=0,指内容表没有记录) -------------------------------------------------------- Begin (标记,二级Begin二) Delete From Navtion_NodeSubject Where fTopID = @fTopID Delete From Navtion_TopSubject Where fTopID = @fTopID End (标记,二级Begin二结束) 以上代码简单,tText表(内容表)没有记录,那么首先删除次类别表Navtion_NodeSubject中的记录,再删除主类别表Navtion_TopSubject中的记录。 ------------------------------------ End (标记,二级Begin结束) ------------------------------------- Else (标记:一级判断否则,表示次类别表没有内容@fNodeCount=0) ------------------------------------------------------------- Begin Delete From Navtion_TopSubject Where fTopID = @fTopID End 上面代码直接删除主类别表Navtion_TopSubject的记录 ----------------------------------------------------- 本来这个触发器已经结束,但是我们必须防止执行出错。所以如果出错,那么要回滚所有操作,并且向应用程序发送错误信息。
复制代码 代码如下:
If @@Error = 0 判断,是否出现错误 @@Error是Sql Server的一个全局变量,保存上一个Sql命令是否出错,如果出错,@@Error=1 如果是0,表示没有出错。 ------------------------------------------- Commit Transaction 上面是没有出错的语句,表示事务提交,(可以看作是结束事务) 如果前面有了Begin Tran开始事务的代码,必须在后面加上这个代码,否则事务不结束,数据库记录将被锁定,无法对数据库记录进行操作! -------------------------------------------- Else @@Error变量大于0,表示出现错误 ---------------------------------- Begin Rollback Transaction my_Save1 Raiserror('删除出现错误,记录:%s及其所属内容没有被删除。',16,1,@fTopName) End