// ------------- 代碼開始 -------------------- 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