都是 IDENTITY惹的禍

2021-04-13 06:30:48 字數 1554 閱讀 3730

前不久系統伺服器出現了一次不大不小事故,資料庫乙個表的資料不翼而飛,這個表雖然算不上頂級重要的表,但也算的上是個很重要的表,大家趕緊查是什麼把這個表的資料刪的只剩下180多條資料.為什麼還有180多條資料存在哪?真是挺讓人納悶的,但發現這180多條資料中有乙個共性,那就是那個不該為空的字段變成了空值.那就查吧,看那些儲存過程這麼霸道,竟如此不講情面,最後查到那個罪魁禍首,那個儲存寫的太不規範了,要不也不至於把乙個表的資料幾乎刪光,先將這個儲存過程改掉,遏制住**,把這張表備份資料還原回來,使伺服器端能正常工作.接下來我們部署相關的環境來查為什麼表裡會產生空值,用監視器跟蹤,跟了幾次幾乎沒發現問題,一切都那麼正常(後來才知道監視器是監視不到觸發器的動作的),最後不得不把監視器所有相關的語句拿到查詢分析器裡面走流程,經過幾次測試,最後發現有些過程聯合起來就會產生空值,而聯合的過程正好在那個表裡有觸發器,問題終於找到了,將觸發器遮蔽掉,聯合測試一切正常.

原來觸發器觸發後會往乙個表中增加記錄,而這個表的id就是identity自動編號,而另外乙個儲存過程也要取identity做為編號往出問題這個表插資料,這兩個identity不期而遇,系統都納悶了,我取那個值哪?想了半天還是認為觸發器那個先,來吧管他三七二十一哪?我就插這個值,結果到好,下面幾個依賴一看取得不正確呀,根本不理,空值出現,害了這張表晚潔不保呀!血淋淋的事實擺在了面前,取全域性變數不是什麼好事,這一點雖然有它的好處,但也有弊端呀!不是嗎?加強程式設計規範還是最重要的,要不撞到北牆要想回頭,也就晚了!

identity相關知識:

1. identity 列不能由使用者直接更新,它是由系統自動維護的。

2.該列資料型別必須為數值型:int, **allint, 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 有意義。

都是埠惹的禍

這幾天公司搬家,所以忙的blog好久都沒有更新,關鍵是沒有什麼技術上的事情,都不知道寫點什麼,呵呵。周四到週日一直在乙個客戶那邊進行產品的實施,整個過程自然比較有趣,對於我來說最重要的就是認識到了靈活程式設計的重要。我們的程式需要幾個通訊埠,其中乙個是1433用來連線sqlserver資料庫,很多的...

都是埠惹的禍

這幾天公司搬家,所以忙的blog好久都沒有更新,關鍵是沒有什麼技術上的事情,都不知道寫點什麼,呵呵。周四到週日一直在乙個客戶那邊進行產品的實施,整個過程自然比較有趣,對於我來說最重要的就是認識到了靈活程式設計的重要。我們的程式需要幾個通訊埠,其中乙個是1433用來連線sqlserver資料庫,很多的...

都是僥倖惹的禍

車開出工業區大門轉入主道500公尺,公升至五檔,速度開始逐步加快,順手開了 精神便不再那麼緊張。咦?車速怎麼忽然減慢,熄火了!有點莫名其妙!重新點火,不著。再點,還是不著!乖乖,這可真是見鬼,車輛川流不息,我的車子停在大路中間,動不了了!趕快開啟雙閃警示燈。幸虧是大白天,否則這種境況很危險滴。我打 ...