對觸發器的思考,觸發器思考

來源:互聯網
上載者:User

對觸發器的思考,觸發器思考

        讀到周洲同學的部落格,看到一篇關於觸發器的文章,是在使用者充值時,需要在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下降沿前接受資訊,在下降沿觸發翻轉,在下降沿後觸發器被封鎖。



 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.