都是@@IDENTITY惹的祸

来源:互联网 发布:怎么开通淘宝卖家账号 编辑:程序博客网 时间:2024/04/30 06:44

       前不久系统服务器出现了一次不大不小事故,数据库一个表的数据不翼而飞,这个表虽然算不上顶级重要的表,但也算的上是个很重要的表,大家赶紧查是什么把这个表的数据删的只剩下180多条数据.为什么还有180多条数据存在哪?真是挺让人纳闷的,但发现这180多条数据中有一个共性,那就是那个不该为空的字段变成了空值.那就查吧,看那些存储过程这么霸道,竟如此不讲情面,最后查到那个罪魁祸首,那个存储写的太不规范了,要不也不至于把一个表的数据几乎删光,先将这个存储过程改掉,遏制住凶手,把这张表备份数据还原回来,使服务器端能正常工作.接下来我们部署相关的环境来查为什么表里会产生空值,用监视器跟踪,跟了几次几乎没发现问题,一切都那么正常(后来才知道监视器是监视不到触发器的动作的),最后不得不把监视器所有相关的语句拿到查询分析器里面走流程,经过几次测试,最后发现有些过程联合起来就会产生空值,而联合的过程正好在那个表里有触发器,问题终于找到了,将触发器屏蔽掉,联合测试一切正常.

   原来触发器触发后会往一个表中增加记录,而这个表的id就是IDENTITY自动编号,而另外一个存储过程也要取IDENTITY做为编号往出问题这个表插数据,这两个IDENTITY不期而遇,系统都纳闷了,我取那个值哪?想了半天还是认为触发器那个先,来吧管他三七二十一哪?我就插这个值,结果到好,下面几个依赖一看取得不正确呀,根本不理,空值出现,害了这张表晚洁不保呀!血淋淋的事实摆在了面前,取全局变量不是什么好事,这一点虽然有它的好处,但也有弊端呀!不是吗?加强编程规范还是最重要的,要不撞到北墙要想回头,也就晚了!

 

IDENTITY相关知识:

1. IDENTITY 列不能由用户直接更新,它是由系统自动维护的。

2.该列数据类型必须为数值型:int, smallint, tinyint, decimal or numeric with scale 0。

3.该列不能为 null。

4.不能在该列上设置缺省值。

5.递增量只能为整形(比如:1,2,-3)。不能为小数,也不能为0。

6.基值(种子值 seed)可以由用户设置,缺省值为1。

理解 @@IDENTITY

@@IDENTITY 返回最后一个插入 IDENTITY 的值,这些操作包括:INSERT, SELECT INTO,或者 bulk copy。如果在给没有 IDENTITY 列的其他表插入记录,系统将其置为 null。如果有多行记录插入到 IDENTITY 表中,@@IDENTITY 表示最后一个产生的值。如果触发了某个触发器,并且这个触发器执行向另一个带有 IDENTITY 列的表的插入操作,@@IDENTITY 将返回这个由触发器产生的值。如果这个触发器插入的表中不包含 IDENTITY 列,那么 @@IDENTITY 将为 null。如果插入操作失败,@@IDENTITY 值依然会增加,所以 IDENTITY 不保证数据的连续性。

@@IDENTITY 是当前连接的全局变量,只对当前连接有效。也就是说,如果断开连接再重新连接后,@@IDENTITY 为 null。以 ADO 来说,@@IDENTITY 在 Connection 对象打开和关闭期间是有意义的,即在 Connection 对象的存在范围内有效。在 MTS 组件中,从打开连接到显式的关闭连接(Connection.Close)或者到调用了 SetAbort,SetComplete之前,在这期间,@@IDENTITY 有意义。

原创粉丝点击