欢迎投稿

今日深度:

对触发器的思考,触发器思考

对触发器的思考,触发器思考


        读到周洲同学的博客,看到一篇关于触发器的文章,是在用户充值时,需要在t_reCharge表中插入一条记录,同时更新t_card表以保证数据一致性.我们当时没想特别多,没想到触发器,就是写了多条sql语句,为了不出错后来使用了事务或存储过程,没记错的话是放在存储过程里了。她是这么实现的:

 

"recharge表中保证提取的是最新一条充值记录,card表中保证更新的记录满足卡号等于充值卡号。"

 

<spanstyle="font-family:FangSong_GB2312;">CREATETRIGGER[dbo].[CardCash]
  on [dbo].[T_Recharge]
  for Insert
 AS
  BEGIN
  UPDATE T_Card set sCash  =sCash +(select top 1 rAdd  fromT_Recharge order by rNo desc) WhereT_Card .cNo in (select top 1 cNo  fromT_Recharge order by rNo desc )  
  END</span>

 

原文链接如下: 

                       给D层减负-存储过程与触发器的使用

 

看到这儿,心里挺佩服小师妹的,不过我还有两个问题:


1. sql语句是硬伤,我可不可以传参呢?


2. 如果有两个卡同时充值,会不会查询到的t_reCharge最新记录是另一个卡的?换句话说,update和insert孰先孰后?其实我一直也没想明白两个卡同时充值到底先插入哪条记录?


3. 如果2中的触发器本身就是事务,保证了要么都执行要么都不执行,就没有这个问题.否则,是不是考虑加上事务呢?

 

        接下来进一步了解了触发器的工作原理。

        由于使表中数据发生变化的操作有插入、更新和删除,所以触发器可以分为三类:INSERT触发器、UPDATE触发器和DELETE触发器。

1.INSERT触发器

当试图向表中插入记录时,INSERT触发器(如果有)自动执行,此时系统自动创建一个inserted表,新的记录被添加到触发器表和inserted表。触发器可以检查inserted表,确定是否执行触发器动作和如何执行触发器动作。

2.DELETE触发器

当试图从表中删除信息时,DELETE触发器被触发,此时系统自动创建一个deleted表,被删除的行被放置到这个特殊的表中。被删除的行在触发器表中将不再存在。因此,触发器表和deleted表之间没有共同的记录。

3.UPDATE触发器

UPDATE语句可以看成两步,删除一条旧记录,插入一条新记录。所以,UPDATE触发器被触发时,自动创建一个deleted表和一个inserted表,UPDATE语句使原始行移入deleted表,将更新行插入到inserted表中。

 

        我们这里是一个insert触发器,那为什么用触发器?用一个类似的例子来解释。我们有两个表用来记录商品的出库入库情况,t_good_store记录库存的产品类别和数量,而t_good_out记录出库的产品类别和数量,那么每当我们出库的某个类别的产品一定数量的时候,我们应该在t_good_out中插入该产品的类别和出库数量,同时也应该在t_good_store中用update来更新库存的相应类别的产品的数量;这时我们要完成两个任务:插入t_good_out后更新t_good_store,为避免只操作其中一个而造成数据的不一致,我们可以用触发器,在t_good_out的插入操作上绑定一个对t_good_store更新的触发器。当然这个过程应该是一个事务,这就不必担心插入t_good_out表执行了,而绑定在这个动作上的触发器操作不会执行,因为数据库设计了原子性。

 

      再来看上面的三个问题.

1. 触发器只有在修改(包括插入和删除)时触发,目的是给我们一个做其他动作的机会,它没有在查询数据时做其他动作的能力.问了触发器是否有参数这个问题,说明我刚开始没有理解触发器的这个特性.

另外,根据触发器的工作原理,我们可以访问inserted和deleted这两张临时表,需要明白的是inserted存放进行insert和update操作后的数据;deleted存放进行delete和update操作前的数据.

Update=delete+insert.这一点给我们的启示:DRP系统中有一个页面是修改Item或者client或者flowCard,可以先都删除再都插入,然后提示修改成功,不然那个样子多的条目,如何一条条判断再modify?


2. 关于同时插入两个记录,有人说可以,因为insert是在毫秒级,但是不管什么级都是有先有后啊.又说,insert是rowlevel锁,如果不Lock table的话,也无法确定先后啊.


3. 我认为可以不加事务,触发器要是设计得insert和update之间还可以容得下其他操作,那就没有什么意义了.

 

        我先实验一把,这个空当,就算抛砖引玉了,当然也会默默地、虚心地接受板砖…



触发器的使用是否方便的思考?

触发器使用最多的地方就是维护数据的完整性,的确,它能实现的东西,在代码里大部份都能实现,但是如果涉及到多用户同时操作的话,在程序里写代码当然比不上在触发器里写代码来的方便。

就拿安全库存来说吧,比如现在有2个用户同时需要出同一种产品,当前库存为100,A用户需要80,B用户需要50;在这之前他们所知道的都是一个数据,即库存为100,他们都认为可以出库,但你会发现一个问题,如果他们都出库的话,库存数明显不够,那么此时如果在程序里写代码的话,就需要进行出库前的判断并做事务处理,但是如果在触发器里写的话,那么A、B用户都可以出库(UPDATE库存),只是有一个用户会被提示库存不足,因为在触发器里已经写了如果当前要出库的数量大于库存则返回一个错误信息。

另外,如果有多个系统(如:WEB系统、桌面系统)同时用到这个数据库的话,只需要在触发器里写相应的维护代码,而不需要同时在各个系统中写同样的代码。

以上所说只是触发器的一方面应用,它也可以做一些其他“善后”工作,有待你去发掘了。

至于测试的话,可以用查询分析器来直接写语句测试。
 

触发器的工作原理是什?

JK触发器是数字电路触发器中的一种电路单元。
JK触发器具有置0、置1、保持和翻转功能,在各类集成触发器中,JK触发器的功能最为齐全。在实际应用中,它不仅有很强的通用性,而且能灵活地转换其他类型的触发器。由JK触发器可以构成D触发器和T触发器。
1.CP=0时,触发器处于一个稳态。CP为0时,G3、G4被封锁,不论J、K为何种状态,Q3、Q4均为1,另一方面,G12、G22也被CP封锁,因而由与或非门组成的触发器处于一个稳定状态,使输出Q、Q状态不变。   
2.CP由0变1时,触发器不翻转,为接收输入信号作准备。
JK触发器电路图:
设触发器原状态为Q=0,Q=1。当CP由0变1时,有两个信号通道影响触发器的输出状态,一个是G12和G22打开,直接影响触发器的输出,另一个是G4和G3打开,再经G13和G23影响触发器的状态。前一个通道只经一级与门,而后一个通道则要经一级与非门和一级与门,显然CP的跳变经前者影响输出比经后者要快得多。在CP由0变1时,G22的输出首先由0变1,这时无论G23为何种状态(即无论J、K为何状态),都使Q仍为0。由于Q同时连接G12和G13的输入端,因此它们的输出均为0,使G11的输出Q=1,触发器的状态不变。CP由0变1后,打开G3和G4,为接收输入信号J、K作好准备。   
3.CP 由1变0时触发器翻转   设输入信号J=1、K=0,则Q3=0、Q4=1,G13和G23的输出均为0。当CP 下降沿到来时,G22的输出由1变0,则有Q=1,使G13输出为1,Q=0,触发器翻转。虽然CP变0后,G3、G4、G12和G22封锁,Q3=Q4=1,但由于与非门的延迟时间比与门长(在制造工艺上予以保证),因此Q3和Q4这一新状态的稳定是在触发器翻转之后。由此可知,该触发器在CP下降沿触发翻转,CP一旦到0电平,则将触发器封锁,处于(1)所分析的情况。   
总之,该触发器在CP下降沿前接受信息,在下降沿触发翻转,在下降沿后触发器被封锁。



 

www.htsjk.Com true http://www.htsjk.com/shujukunews/4054.html NewsArticle 对触发器的思考,触发器思考 读到周洲同学的博客,看到一篇关于触发器的文章,是在用户充时,需要在t_reCharge表中插入一条记录,同时更新t_card表以保证数据一致性.我们当时没想特别多...
评论暂时关闭