使用觸發器

摘要: 本篇博客僅做爲筆記,若有侵權,請聯繫,當即刪除(網上找博客學習,而後手記筆記,因紙質筆記不便保存,因此保存到網絡筆記)。數據庫

  本博客學習什麼是觸發器,爲何要使用觸發器以及如何使用觸發器。本博客還介紹建立和使用觸發器的語法。安全

  1、觸發器網絡

注意:須要MySQL 5  對觸發器的支持是在MySQL 5中增長的。所以,本博客內容適用於MySQL 5或之後的版本。學習

  MySQL語句在須要時被執行,存儲過程也是如此。可是,若是你想要某條語句(或某些語句)在事件發生時自動執行,怎麼辦呢?例如:測試

  (1)每當增長一個顧客到某個數據庫表時,都檢查其電話號碼格式是否正確,州的縮寫是否爲大寫;spa

  (2)每當訂購一個產品時,都從庫存數量中減去訂購的數量;code

  (3)不管什麼時候刪除一行,都在某個存檔表中保留一個副本。blog

  全部這些例子的共同之處是它們都須要在某個表發生更改時自動處理。這確切地說就是觸發器。觸發器是MySQL響應如下任意語句而自動執行的一條MySQL語句(或位於BEGIN和END語句之間的一組語句):事件

  (1)DELETE;博客

  (2)INSERT;

  (3)UPDATE;

  其餘MySQL語句不支持觸發器。

  2、建立觸發器

  在建立觸發器時,須要給出4條信息:

  (1)惟一的觸發器名;

  (2)觸發器關聯的表;

  (3)觸發器應該相應的活動(DELECT、INSERT或UPDATE);

  (4)觸發器什麼時候執行(處理以前或以後)。

注意:保持每一個數據庫的觸發器名惟一  在MySQL 5中,觸發器名必須在每個表中惟一,但不是在每一個數據庫中惟一。這表示同一數據庫中的兩個表可具備相同名字的觸發器。這在其餘每一個數據庫觸發器名必須惟一的DBMS中是不容許的,並且之後的MySQL版本極可能會使命名規則更嚴格。所以,如今最好是在數據庫範圍內使用惟一的觸發器名。

  觸發器用CREATE TRIGGER語句建立。下面是一個簡單的例子:

CREATE TRIGGER newproduct AFTER INSERT ON products
FOR EACH ROW SELECT 'Product added';

  分析:CREATE TRIGGER用來建立名爲newproduct的新觸發器。觸發器可在一個操做發生以前或以後執行,這裏給出了AFTER INSERT,因此此觸發器將在INSERT語句成功執行。這個觸發器還指定FOR EACH ROW,所以代碼對每一個插入行執行。在這個例子中,文本Product added將對每一個插入的行顯示一次。

  爲了測試這個觸發器,使用INSERT語句添加一行或多行到products中,你將看到對每一個成功的插入,顯示Product added消息。

注意:僅支持表  只有表才支持觸發器,視圖不支持(臨時表也不支持)。

  觸發器按每一個表每一個事件每次地定義,每一個表每一個事件每次只容許一個觸發器。所以,每一個表最多支持6個觸發器(每條INSERT、UPDATE和SELECT的以前和以後)。單一觸發器不能與多個事件或多個表關聯,因此,若是你須要一個對INSERT和UPDATE操做執行的觸發器,則應該定義兩個觸發器。

注意:觸發器失敗  若是BEFORE觸發器失敗,則MySQL將不執行請求的操做。此外若是BEFORE觸發器或語句自己失敗,MySQL將不執行AFTER觸發器(若是有的話)。

  3、刪除觸發器

  如今,刪除觸發器的語法應該很明顯了。爲了刪除一個觸發器,可以使用DROP TRIGGER語句,以下所示:

DROP TRIGGER newproduct;

  分析:觸發器不能更新或覆蓋。爲了修改一個觸發器,必須先刪除它,而後再從新建立。

  4、使用觸發器

  在有了前面的基礎知識後,咱們如今來看所支持的每種觸發器類型以及它們的差異。

  一、INSERT觸發器

  INSERT觸發器在INSERT語句執行以前或以後執行。須要知道如下幾點:

  (1)在INSERT觸發器代碼內,可引用一個名爲NEW的虛擬表,訪問被插入的行;

  (2)在BEFORE INSERT觸發器中,NEW中的值也能夠被更新(容許更改被插入的值);

  (3)對弈AUTO_INCREMENT列,NEW在INSERT執行以前包含0,在INSERT執行以後包含新的自動生成值。

  下面舉一個例子(一個實際有用的例子)。AUTO_INCREMENT列具備MySQL自動賦予的值。

CREATE TRIGGER neworder AFTER INSERT ON orders
FOR EACH ROW SELECT NEW.order_num;

  分析:此代碼建立一個名爲neworder的觸發器,它按照AFTER INSERT ON orders執行。在插入一個新訂單到orders表時,MySQL生成一個新訂單號並保存到order_num中。觸發器從NEW.order_num取得這個值並返回它。此觸發器必須按照AFTER INSERT執行,由於在BEFORE INSERT語句執行以前,新order_num還沒生成。對於orders的每次插入使用這個觸發器將老是返回新的訂單號。

  爲測試這個觸發器,試着插入一下新行,以下所示:

INSERT INTO orders(order_date,cust_id)
VALUES(NOW(),10001);

  分析:order包含3個列。order_date和cust_id必須給出,order_num由MySQL自動生成,而如今order_num還自動被返回。

注意:BEFORE或AFTER?  一般,將BEFORE用於數據驗證和淨化(目的是保證插入表中的數據確實是須要的數據)。本提示也適用於UPDATE觸發器。

  二、DELETE觸發器

  DELETE觸發器在DELETE語句執行以前或以後執行。須要知道如下兩點:

  (1)在DELETE觸發器代碼內,你能夠引用一個名爲OLD的虛擬表,訪問被刪除的行;

  (2)OLD中的值全都是隻讀的,不能更新。

  下面的例子演示使用OLD保存將要被刪除的行到一個存檔表中:

CREATE TRIGGER deleteorder BEFORE DELETE ON orders
FOR EACH ROW
BEGIN
    INSERT INTO archive_orders(order_num,order_date,cust_id)
    VALUES(OLD.order_num,OLD.order_date,OLD.cust_id);
END;

  分析:在任意訂單被刪除前將執行此觸發器。它使用一條INSERT語句將OLD中的值(要被刪除的訂單)保存到一個名爲archive_orders的存檔表中(爲實際使用這個例子,你須要用與orders相同的列建立一個名爲archive_orders的表)。

  使用BEFORE DELETE觸發器的優勢(相對於AFTER DELETE觸發器來講)爲,若是因爲某種緣由,訂單不能存檔,DELETE自己將被放棄。

注意:多語句觸發器  正如所見,觸發器deleteorder使用BEGIN和END語句標記觸發器體。這在此例子中並非必需的,不過也沒有害處。使用BEGIN END塊的好處是觸發器能容納多條SQL語句(在BEGIN END塊中一條挨着一條)。

  三、UPDATE觸發器

  UPDATE觸發器在UPDATE語句執行以前或以後執行。須要知道如下幾點:

  (1)在UPDATE觸發器代碼中,你能夠引用一個名爲OLD的虛擬表訪問之前(UPDATE語句前)的值,引用一個名爲NEW的虛擬表訪問新更新的值;

  (2)在BEFORE UPDATE觸發器中,NEW中的值可能也被更新(容許更改將要用於UPDATE語句中的值);

  (3)OLD中的值全都是隻讀的,不能更新。

  下面的例子保證州名縮寫老是大寫(無論UPDATE語句中給出的是大寫仍是小寫):

CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors
FOR EACH ROW SET NEW.vend_state = Upper(NEW.vend_state);

  分析:顯然,任何數據淨化都須要在UPDATE語句以前進行,就像這個例子中同樣。每次更新一個行時,NEW.vend_state中的值(將用來更新錶行的值)都用Upper(NEW.vend_state)替換。

  四、關於觸發器的進一步介紹

  在結束這一博客內容以前,咱們再介紹一些使用觸發器時須要記住的重點。

  (1)與其餘DBMS相比,MySQL 5中支持的觸發器至關初級。將來的MySQL版本中有一些改進和加強觸發器支持的計劃。

  (2)建立觸發器可能須要特殊的安全訪問權限,可是,觸發器的執行時自動的。若是INSERT、UPDATE和DELETE語句可以執行,則相關的觸發器也能執行。

  (3)應該用觸發器來保證數據的一致性(大小寫、格式等)。在觸發器中執行這種該類型的處理的優勢是它老是進行這種處理,並且是透明地進行,與客戶機應用無關。

  (4)觸發器的一種很是有意義的使用是建立審計跟蹤。使用觸發器,把更改(若是須要,甚至還有以前和以後的狀態)記錄到另外一個表很是容易。

  (5)遺憾的是,MySQL觸發器中不支持CALL語句。這表示不能從觸發器內調用存儲過程。所需的存儲過程代碼須要複製到觸發器內。

  5、小結

  本博客介紹了什麼是觸發器以及爲何要使用觸發器,學習了觸發器的類型和什麼時候執行它們,列舉了幾個用於INSERT、DELETE和UPDATE操做的觸發器例子。

相關文章
相關標籤/搜索