<sub id="jk0bf"><listing id="jk0bf"></listing></sub>

<nav id="jk0bf"><table id="jk0bf"></table></nav><form id="jk0bf"></form>
<nav id="jk0bf"><address id="jk0bf"></address></nav>

      <form id="jk0bf"><legend id="jk0bf"><noscript id="jk0bf"></noscript></legend></form>
      當前位置:首頁 > 新聞中心 > 企業動態
      返回

      SQL程序設計 創建一個觸發器

      • 發布時間:2020-01-19
      • 瀏覽次數:340
      我發現編寫一個SQL觸發器需要額外的考慮,如果我們不小心,我們可能會以比開始時更大的混亂告終。本文旨在涵蓋我們可以使用的所有陷阱和技術,以確保當我們用觸發器構建數據庫時,它們將為我們的利益而工作,而不僅僅是為了復雜性而增加復雜性。

      讓我們考慮一下規則…

      規則1:不要使用扳機!

      說真的。如果你早上第一件事就是伸手去拿扳機,那么晚上你會后悔的。觸發器通常最大的問題是,它們會有效地混淆您的業務邏輯,并干擾不需要觸發器的流程。我已經看到一些建議,當您進行批量加載或類似操作時,可以關閉觸發器。我斷言這是一種巨大的代碼味道。如果必須有條件地打開或關閉觸發器,就不應該使用它。

      默認情況下,我們應該首先編寫存儲過程或視圖。對于大多數情況,他們會做得很好。我們不要在這里增加魔力。

      那為什么這篇關于觸發器的文章?

      因為觸發器確實有其用途。我們需要認識到什么時候應該使用觸發器。我們還需要以一種幫助我們多于傷害我們的方式來寫它們。

      規則2:我真的需要扳機嗎?

      理論上,觸發器聽起來不錯。它們為我們提供了一個基于事件的模型,以便在變更被修改后立即進行管理。但是如果你只需要驗證一些數據,或者確保一些隱藏的列或者日志表被填充…我想您會發現存儲過程可以更有效地完成工作,并且消除了神奇的方面。此外,編寫存儲過程很容易測試;只需設置一些模擬數據并運行存儲過程,驗證結果是否符合您的預期。我希望您正在使用像tSQLt這樣的測試框架。

      需要注意的是,使用數據庫約束通常比觸發器更有效。因此,如果您只需要驗證一個值在另一個表中是否有效,請使用外鍵約束。驗證值是否在特定范圍內需要檢查約束。對于這種驗證,這些應該是您的默認選擇。

      那么我們什么時候真正需要一個觸發器呢?

      歸根結底,您確實希望業務邏輯位于SQL層??赡苁且驗槟卸鄠€不同編程語言的客戶端在對表進行插入/更新。用各自的編程語言在每個客戶機上復制業務邏輯會非常麻煩,這也意味著更多的錯誤。對于創建中間層不切實際的場景,觸發器是您執行不能表示為約束的業務規則的最佳行動方案。

      使用特定于訪問的示例。假設我們想要在通過應用程序修改數據時強制執行業務邏輯。也許我們有多個綁定到同一個表的數據輸入表單,或者也許我們需要支持復雜的數據輸入表單,其中多個基表必須參與編輯。也許數據條目表單需要支持非規范化條目,然后我們將它們重新組合成規范化數據。在所有這些情況下,我們可以只編寫VBA代碼,但是這對于所有情況來說都很難維護和驗證。觸發器有助于我們將邏輯從VBA轉移到事務處理語言中。以數據為中心的業務邏輯通常最接近數據。

      規則3:觸發器必須基于設置,而不是基于行

      到目前為止,觸發器最常見的錯誤是讓它按行運行。我們經??吹筋愃七@樣的代碼:
      -錯誤的代碼!不要使用!
      創建觸發器dbo。SomeTrigger
      直播。插入后可測量
      如同
      開始
      申報@新鴻碩網絡IT外包;
      DECLARE @ NewID int

      選擇前1名
      @NewID = SalesOrderID,
      @IT外包=銷售額
      插入自;

      更新dbo。銷售訂單
      設置訂單總數=訂單總數+@鴻碩網絡IT外包
      其中SalesOrderID = @SalesOrderID
      結束;

      泄露的事實應該是選擇前1名離開a桌子 插入的。只要我們只插入一行,這就行。但是當它超過一行時,那些排在第二和第二后面的不幸的行會發生什么呢?我們可以通過做類似的事情來改善這一點:
      -還是糟糕的代碼!不要使用!
      創建觸發器dbo。SomeTrigger
      直播。插入后可測量
      如同
      開始
      并入dbo。銷售訂單為s
      使用插入的AS i
      ON s . SalesOrderID = I . SalesOrderID
      訂單總計=訂單總計+@鴻碩網絡
      ;
      結束;

      現在這是基于集合的,因此有了很大的改進,但是這仍然有其他的問題,我們將在接下來的幾個規則中看到…

      規則4:改用視圖。

      視圖可以附加觸發器。這為我們提供了避免與表觸發器相關聯的問題的優勢。我們將能夠輕松地將干凈數據大容量導入到表中,而不必禁用任何觸發器。此外,視圖中的觸發器使其成為明確的選擇加入選項。如果您有需要運行觸發器的安全相關功能或業務規則,您可以直接撤銷對表的權限,從而將它們引導到新視圖。這確保了您將完成整個項目,并記錄需要對表進行更新的地方,這樣您就可以跟蹤它們以發現任何可能的錯誤或問題。

      缺點是視圖只能有一個代替附加觸發器,這意味著您必須在觸發器內自己對基表顯式執行等效的修改。然而,我傾向于認為這樣更好,因為這樣還可以確保您確切知道修改的內容,從而給予您通常在存儲過程中擁有的相同級別的控制。

      規則5:觸發器應該很簡單。

      還記得關于調試和測試存儲過程的注釋嗎?我們能為自己做的最好的事情是將業務邏輯保存在存儲過程中,并讓觸發器調用它。永遠不要將業務邏輯直接寫入觸發器;這實際上是在數據庫中澆注混凝土?,F在它被凍結在形狀上,要充分測試邏輯可能會有問題。您的測試工具現在必須包含對基表的一些修改。這不利于編寫簡單且可重復的測試。這應該是最復雜的,因為您的觸發器應該是:

      創建觸發器[dbo]。[·IT外包]
      [IT]。[外包]代替插入,更新,刪除
      如同
      開始
      將@SomeIDs聲明為SomeIDTableType

      -在基表中執行合并
      并入dbo。有時像t
      使用插入的AS i
      ON t . SomeIDID = i . SomeID
      匹配時,更新設置
      t.一些東西=我。一些東西,
      t.其他東西=我,其他東西
      當不匹配時,插入(
      一些東西,
      其他東西
      )VALUES(
      I .一些東西,
      I .其他材料
      )
      插入輸出。some id INTO @ some id(some id);

      從數據庫中刪除。有時
      輸出已刪除。some id INTO @ some id(some id)
      哪里存在(
      選擇空值
      從已刪除的AS d
      其中d.SomeID = SomeTable。SomeID
      )和不存在(
      選擇空值
      從插入為I
      我在哪里。某個人=某個人。SomeID
      );

      EXEC dbo . USupdateSomeStuff @ SomeIds;
      結束;

       

      更重要的是,這種方法也為我們提供了一種簡單的方法來修正總數。假設我們必須進行批量導入,而導入不包含總數,所以我們必須自己計算。我們可以編寫存儲過程直接寫入表。然后我們可以調用上面的存儲過程,從導入中傳遞IDs,我們都很好。因此,我們使用的邏輯并不局限于視圖背后的觸發器。當邏輯對于我們正在執行的批量導入是不必要的時,這將有所幫助。

      如果您發現自己無法使觸發器等冪,這強烈表明您可能需要使用存儲過程,并直接從應用程序調用它,而不是依賴觸發器。這個規則的一個值得注意的例外是觸發器主要是審計觸發器。在這種情況下,您確實希望為每次編輯向審核表中寫入新行,包括用戶犯的所有打字錯誤。這是可以的,因為在這種情況下,用戶正在交互的數據沒有變化。從用戶的角度來看,結果還是一樣的。但是每當觸發器需要處理用戶正在處理的相同數據時,當它是冪等的時會好得多。

       

      狠狠任你日线观看免费,日本亚洲三级片,欧美日韩亚洲中字国产,欧美日韩一中文字不卡