zoukankan      html  css  js  c++  java
  • .NET重构(三):在注册和充值中,触发器的使用

    导读:机房做到注册和充值了,有两个关键点:在注册的时候,同时给该用户写入充值记录;在充值的时候,给该用户更改余额信息。第一次做的时候,是一条一条的写,那时候师傅就说了触发器和存储过程的使用,现在终于用上了。针对本次使用触发器的情况,做一个说明。


    一、What(是什么)?


    触发器(Trigger):是一个能有系统自动执行对数据库修改的语句。由三部分组成:一、事件:事件是指对数据库的插入,删除,修改等操作。触发器在这些事件发生时开始工作。二、条件:触发器将测试条件是否成立。成立则执行相应的动作,否则不执行。三、动作。如果触发器测试满足预定的条件,那么,就由DBMS执行这些动作。同时,触发器也是一种特殊类型的存储过程,不由用户直接调用。

    触发器的类别:

    1,( 数据操纵语言 Data Manipulation Language)触发器:是指触发器在数据库中发生DML事件时将启用。DML事件即指在表或视图中修改数据的insert、update、delete语句。

    2,DDL(数据定义语言 Data Definition Language)触发器:是指当服务器或数据库中发生(DDL事件时将启用。DDL事件即指在表或索引中的create、alter、drop语句也。

    3,登陆触发器:是指当用户登录SQL SERVER实例建立会话时触发。

    我的理解:满足某一个或多个条件时,使另一事件执行。就像杯子的水装满了,就会触发溢出事件一样。在这里就是,当学生成功注册后,同时写入充值记录;当充值成功后,同时更改余额。

    PS:条件是成功注册、充值。(这里可以结合事务学习)


    二、Why(优点)


    1,触发器可通过数据库中的相关表实现级联更改;不过,通过级联引用完整性约束可以更有效地执行这些更改。

    2,触发器可以强制比用 CHECK 约束定义的约束更为复杂的约束。

    3,与 CHECK 约束不同,触发器可以引用其它表中的列。例如,触发器可以使用另一个表中的 SELECT 比较插入或更新的数据,以及执行其它操作。


    三、How(怎么用)


    1,注册时,同时写记录到充值表:

    <span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">-- =============================================
    -- Author:		<何下下>
    -- Create date: <2015/1/6>
    -- Description:	<在注册表插入数据时,在充值表中插入一条数据>
    -- =============================================
    ALTER TRIGGER [dbo].[UpdateRecharge]--写入触发器的名称
       ON  [dbo].[TC_StudentInfo] --创建触发器的表
       AFTER INSERT--在插入事件之后触发
    AS 
    --定义变量
    declare @CardID char(10),     
              @UserName char(10),  
              @SDate char(10),  
              @STime char(10),    
              @Cash numeric(18,1),
              @ChkState char(10)
    		  --通过查询给变量赋值  
              select @UserName =UserName FROM inserted 
              select @CardID =CardID from inserted  
              select @SDate  = SDate  from inserted   
              select @STime=STime from inserted 
    		  select @Cash =Cash from inserted  
              select @ChkState=ChkState from inserted
             
    BEGIN
    	
    	SET NOCOUNT ON;
    	--向充值记录表中插入数据
    	insert into TC_RechargeInfo (CardID ,States  ,RDate ,RTime ,AddCash ,UserID ) values (@CardID ,@ChkState ,@SDate ,@STime ,@Cash ,@UserName )
    END
    </span></span>
    说明:

    1,ALTER TRIGGER :因为我开始建了一个失败的触发器,在原来的基础上进行修改,所以ALTER TRIGGER ,而不是Create。

    2,AFTER INSERT :这里是在注册表中插入一条记录之后运行触发器(条件,学生注册成功),在这个位置,还有after delete,after update。

    after:触发器在触发它们的语句完成后执行。如果该语句因错误而失败,触发器将不会执行。

    PS:不能为视图指定after触发器,只能为表指定该触发器。可以为表指定一个或多个触发器,除了可以用sp_settriggerorder控制第一个和最后一个,其他的,无法控制其顺序。


    2,充值时,更改学生余额信息

    <span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">-- =============================================
    -- Author:		<何下下>
    -- Create date: <2015/1/6>
    -- Description:	<充值成功后,更改学生表里的余额>
    -- =============================================
    ALTER TRIGGER [dbo].[UpdateBalance]--触发器名称
       ON  [dbo].[TC_RechargeInfo]--创建位置
      after insert--在插入数据之后
    AS 
    
    --定义变量
    declare @IntRows int,
    		@CardID char(10),
    		@AddCash numeric(18,1)
    
    --通过查询为变量赋值
    	select @AddCash=AddCash from inserted
    	select @CardID=CardID from inserted
    	select @IntRows=count(CardID) from inserted
    	--如果该卡号的充值记录大于1
    	if @IntRows >1
    
    BEGIN
    	
    	SET NOCOUNT ON;
    	--更改余额
    	update TC_StudentInfo set Cash =Cash +@AddCash where CardID=@CardID 
    
    	
    END
    </span></span>

    说明:

    1,if @IntRows >1:刚开始的时候,是没有这一个判断的,所以就导致了我每注册一个新用户,他的余额都是充值金额的2倍。因为写入注册表的时候,触发向充值表中写数据。而像充值表中写数据,又触发了更改余额。后来,我就想到了加上这一个判断:如果充值表中该卡号的记录为1,说明是刚注册的新用户,这时候,用户的余额就是他注册时的充值金额,不需要触发更改余额的事件。

    2,from inserted,inserted是SQLServer为每个触发器创建的临时数据表之一,另一个是Deleted表。这两个表由系统来维护,它们存在于内存中而不是数据库中。这两个表的结构总是与被该触发器作用的表的结构相同,触发器执行完成后,与该触发器相关的这两个表也被删除。 (这个挺好的,给我的感觉就是,你只管拿去用,别的都别管了,系统创建,系统维护,系统删除)

    PS:inserted表和deleted表的区别

    Deleted 表:用于存储 DELETE 和 UPDATE 语句所影响的行的复本。在执行 DELETE 或 UPDATE 语句时,行从触发器表中删除,并传输到 deleted 表中。(我认为deleted表有类似于回收站的作用)Deleted 表和触发器表通常没有相同的行。

    Inserted 表:用于存储 INSERT 和 UPDATE 语句所影响的行的副本。在一个插入或更新事务处理中,新建行被同时添加到 inserted 表和触发器表中。Inserted 表中的行是触发器表中新行的副本。

    Inserted表和Deleted表的区别

    Inserted表 Deleted表
    插入Insert 有数据 无数据
    删除Delete 无数据 有数据
    更新Update 有数据(新) 有数据(旧)

    四、总结

    过多触发器会造成数据库及应用程序的维护困难,同时对触发器过分的依赖,势必影响数据库的结构,同时增加了维护的复杂程序。总体说来,触发器的耦合性太强,所以,虽然触发器可以给我们带来很多便利,但仍须慎用!


    请大家多多指教!


  • 相关阅读:
    用Total Commander for Android管理应用程序
    我的zsh简单设置
    C# Newtonsoft.Json 使用
    Wireshark 抓包 test
    C# 调用API test
    C# 委托 的语法 之一
    C# 对象初始化器 和数组初始化语法
    C 语言 数据类型长度
    vue 使用 test
    test
  • 原文地址:https://www.cnblogs.com/hhx626/p/6010456.html
Copyright © 2011-2022 走看看