sqlserver 触发器教程

主类别表名:Navtion_TopSubject 主键fTopID Char(36)
次类别表名:Navtion_NodeSubject 外键同上
内容表名:tText 外键同上
<div class="codetitle"><a style="CURSOR: pointer" data="3402" class="copybut" id="copybut3402" onclick="doCopy('code3402')"> 代码如下:

<div class="codebody" id="code3402">
// ------------- 代码开始 --------------------
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命令,转向执行触发器的命令
(多说一句:除了INSTEAD OF关键字,还有 For关键字,表示这个触发器在执行完传递进来的Sql语句后执行触发器内容,一般用在Insert和Update中)
DELETE : 表示此触发器的触发条件是Delete命令,如果对这个表作删除操作,将执行这个触发器的代码。
As 表示下面的代码是触发器的代码:
-------------------------------------------------------------------
/ 定义触发器使用的变量 /
DECLARE
@fTopID Char,
@fTopName VarChar
以上命令是定义触发器使用的变量,DECLARE 命令相当于VBScript的Dim命令,不过这个语句可以定义多变量,不用一个变量一个命令,变量之间用英文逗号分隔。
@fTopID 是变量名,SqlServer规定,在SqlServer中使用的变量名前面必须加入@字符。
变量后面是变量类型 Char是固定长度的字符串,Int是整数数字类型,VarChar是可变长度的字符串。
--------------------------------------------------------------------------
/ 把传送的需要删除的fTopID键值赋值给@fTopID变量 /
/ 开始事务 /
BEGIN TRAN Remove_TopSubject
Set @fTopID = (Select fTopID From deleted) / 保存删除前保存点,防止出错 /
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的记录
-----------------------------------------------------
本来这个触发器已经结束,但是我们必须防止执行出错。所以如果出错,那么要回滚所有操作,并且向应用程序发送错误信息。
<div class="codetitle"><a style="CURSOR: pointer" data="95116" class="copybut" id="copybut95116" onclick="doCopy('code95116')"> 代码如下:
<div class="codebody" id="code95116">
If @@Error = 0
判断,是否出现错误
@@Error是Sql Server的一个全局变量,保存上一个Sql命令是否出错,如果出错,@@Error=1
如果是0,表示没有出错。
-------------------------------------------
Commit Transaction
上面是没有出错的语句,表示事务提交,(可以看作是结束事务)
如果前面有了Begin Tran开始事务的代码,必须在后面加上这个代码,否则事务不结束,数据库记录将被锁定,无法对数据库记录进行操作!
--------------------------------------------
Else
@@Error变量大于0,表示出现错误
----------------------------------
Begin
Rollback Transaction my_Save1
Raiserror('删除出现错误,记录:%s及其所属内容没有被删除。',@fTopName)
End

上面的代码是个语句块,表示如果上面的删除语句出错后怎么办
Rollback Transaction my_Save1
Rollback Transaction 是Sql Server的内部命令,表示回滚事务,就是以前的操作全部取消。my_Save1是上面保存的保存点的名称。
这个代码意思和玩游戏中没有过关,从存盘文件中恢复的道理一样。 :D
----------------------------------------------------------------------
Raiserror('删除出现错误,记录:%s及其所属内容没有被删除。',@fTopName)
Raiserror表示自定义错误信息,这个语句的作用是向使用Sql Server的应用程序发送信息。
如asp的代码,asp代码获得这个信息将显示在网页上。
16,1是错误的等级号码,这个我不做过多解释,有兴趣的人可以查看SQL Server联机丛书的
T-SQL语言参考。
%s是Reiserror命令的自定义变量 %s表示字符串变量,内容是后面的@fTopName的内容。
这个语句类似于以下VBScript代码(假设VBscript中有Raiserror命令)
Raiserror('删除出现错误,记录:' & @fTopName & '及其所属内容没有被删除。',1)
-------------------------------------------------------------
好了,这个触发器所有代码我都详细解释了,希望大家看得懂,并且通过上面的解释提高数据库操作的能力!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


本篇内容主要讲解“sqlalchemy的常用数据类型怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“sqlalche...
今天小编给大家分享一下sqlServer实现分页查询的方式有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家
这篇文章主要介绍“sqlmap之osshell怎么使用”,在日常操作中,相信很多人在sqlmap之osshell怎么使用问题上存在疑惑,小编查阅了各式资料,整理出
本篇内容介绍了“SQL注入的知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
1. mssql权限sa权限:数据库操作,文件管理,命令执行,注册表读取等system。是mssql的最高权限db权限:文件管理,数据库操作等 users-administratorspublic权限:数据库操作 guest-users2、sql server注入执行命令查
sql执行计划如何查看?在SPL庞大的数据中我们不知道如何查看实际数据库中发生了什么事情,有必要定期进行查询优化和索引否则会影响我们后期的SQL的查询速度。那么针对这样的问题我们必须要知道SQL执行的计划,在本文中winwin7小编给大家分享下SQL执
SQL Server 是Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相关软件集成程度高等优点应用非常广泛。不过在使用中,我们会遇到非常多的错误,面对这么庞大的数据库环境,当然会有精确的错误代码的对照季,下面小编分享的
SQL Server本地账户无法登陆出现错误提示:error:40-Could not open a connenction to SQL Server的问题很常见,对于初学者来说可能不知道如何解决,一起来看看下面的解决方案。解决步骤如下:1、这种情况需要开启 SQL Server service
微软推出的SQL2008是一款非常好用的数据库软件,它稳定、功能强大,为众多企业提供了最佳的数据库解决方案,那么我们如何在Windows中安装它呢,一些朋友对SQL Server 2008的安装过程还不是很熟悉,下面就一起来看看SQL Server 2008详细安装图解...
本页概要如果您使用的是 SQL Server 2005备份和还原Sp_detach_db 和 Sp_attach_db 存储过程关于排序规则的说明导入和导出数据(在 SQL Server 数据库之间复
DBCC CHECKIDENT 检查指定表的当前标识值,如有必要,还对标识值进行更正。 语法 DBCC CHECKIDENT ( &#39;table_name&#39; [ , { NORESEED
这里对 SQL Server 字符串函数进行分门别类地列出,便于查阅和记忆,相信大家都在其它方面有高深的编程基础,从字面上来说大家都知道这些函数的意义,就不对这些函数作过多的解释了,主要谈些经验,具体
查询及删除重复记录的方法 1、查找表(people)中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select*frompeoplewherepeopleIdin(selectpe
微软发SQL Server 2008第二个CTP预览版from: http://news.csdn.net/n/20070807/107158.html8月7日消息,微软公司本周发布了SQL Serv
症状当您将数据库备份恢复到另一台服务器时,可能会遇到孤立用户的问题。SQL Server 联机丛书中的孤立用户疑难解答主题中没有讲述解决此问题的具体步骤。本文介绍了如何解决孤立用户问题。更多信息虽然术
当登录SQL Server 2005时可能碰到错误: &#39;No Process is on the Other End of the Pipe&#39;。解决方法:(1)Open up SQL
概要本文描述如何映射标准登录和集成登录来解决在运行 SQL Server 的服务器之间移动数据库时的权限问题。更多信息当您将数据库从一个运行 SQL Server 的服务器移到另一个运行 SQL Se
----------------------------------------问题:该用户与可信的SQL SERVER 连接无关联使用sa用户或自建用户使用“SQL SERVER 身份认证”连接数据
更新日期: 2007 年 5 月 20 日 使用下表可以确定各种版本的 Microsoft SQL Server 2005 支持哪些功能。有关 SQL Server 2005 Enterprise E
当从Excel导入数据到Sql Sever中,可能会出现以下问题:&#xD;&#xA;对于指定的缓冲区大小而言,源列的数据太大