mysql 觸發器介紹


觸發器(Trigger)是 MySQL 中非常實用的一個功能,它可以在操作者對表進行「增刪改」 之前(或之后)被觸發,自動執行一段事先寫好的 SQL 代碼。

本教程帶領大家在實踐中學習,你將學到觸發器在實際應用場景中的重要應用。

在這個教程中客戶管理系統。在這套系統中,你需要設置在INSERT 表之前檢測操作者是否輸入錯誤數據、在 UPDATE 時,記錄操作者的行為 log ,以及在DELETE 時,判斷刪除的信息是否符合刪除規則。 這三類操作都可以使用 MySQL 觸發器來實現。

下面將詳細講解觸發器全部六種情況

  1. BEFORE INSERT : 在插入數據前,檢測插入數據是否符合業務邏輯,如不符合返回錯誤信息。
  2. AFTER INSERT : 在表 A 創建新賬戶后,將創建成功信息自動寫入表 B 中。
  3. BEFORE UPDATE :在更新數據前,檢測更新數據是否符合業務邏輯,如不符合返回錯誤信息。
  4. AFTER UPDATE :在更新數據后,將操作行為記錄在 log 中
  5. BEFORE DELETE :在刪除數據前,檢查是否有關聯數據,如有,停止刪除操作。
  6. AFTER DELETE :刪除表 A 信息后,自動刪除表 B 中與表 A 相關聯的信息。

先決條件

在開始之前,請確保您具備以下條件:

  • 一台配置好的 Ubuntu 服務器,root 賬號。
  • 服務器上配置好 MySQL Server
  • MySQL root 賬號

創建示例數據庫

我們先創建一個干凈的示例數據庫,方便大家可以跟隨本教程一起實踐。我們會在這個數據庫中演示 MySQL 觸發器的多種工作方式。

首先,以 root 身份登錄到你的 MySQL 服務器:

mysql -u root -p

出現提示時,請輸入你 MySQL root 賬號的密碼,然后點擊 ENTER 繼續。看到 mysql> 提示后,運行以下命令,創建 demo_kalacloud 數據庫:

CREATE database demo_kalacloud;

輸出結果

Query OK, 1 row affected (0.00 sec)

接下來,切換到新建的 demo_kalacloud 數據庫:

USE demo_kalacloud;

輸出結果

Database changed

接着創建一個 customers 表。我們使用這個表記錄銀行客戶的信息。這個表包括 customer_idcustomer_name,和level。咱們先把客戶分為兩個級別:BASICVIP

create table customers( 
customer_id BIGINT PRIMARY KEY,  
customer_name VARCHAR(50), level VARCHAR(50) 
) ENGINE=INNODB;

輸出結果

Query OK, 0 rows affected (0.01 sec)

接着,我們向 customers 表中添加一些客戶記錄。

Insert into customers (customer_id, customer_name, level )values('1','Jack Ma','BASIC'); 
Insert into customers (customer_id, customer_name, level )values('2','Robin Li','BASIC'); 
Insert into customers (customer_id, customer_name, level )values('3','Pony Ma','VIP');

分別運行三個 INSERT 命令后,命令行輸出成功信息。

輸出結果

Query OK, 1 row affected (0.01 sec)

我們使用 SELECT 檢查一下三條信息是否已經寫入表中:

Select * from customers;

輸出結果

 

下面我們創建另一個表customer_status,用於保存 customers 表中客戶的備注信息。

這個表包含 customer_idstatus_notes 字段:

Create table customer_status(customer_id BIGINT PRIMARY KEY, status_notes VARCHAR(50)) ENGINE=INNODB;

然后,我們再創建一個 sales 表,這個表與 customer_id 關聯。保存與客戶有關的銷售數據。

Create table sales(sales_id BIGINT PRIMARY KEY, customer_id BIGINT, sales_amount DOUBLE ) ENGINE=INNODB;

輸出結果:

Query OK, 0 rows affected (0.01 sec)

最后一步,我們再建一個 audit_log 表,用來記錄操作員操作系統時的操作行為。方便管理員在發生問題時,有 log 可查。

Create table audit_log(log_id BIGINT PRIMARY KEY AUTO_INCREMENT, sales_id BIGINT, previous_amount DOUBLE, new_amount DOUBLE, updated_by VARCHAR(50), updated_on DATETIME ) ENGINE=INNODB;

輸出結果

Query OK, 0 rows affected (0.02 sec)

至此,已經把客戶管理系統表建立完成。接下來,我們將對這個管理系統的關鍵節點增加對應的觸發器。

1.BEFORE INSERT 觸發器使用方法

作為嚴謹的管理系統,對任何寫入系統的數據都應該提前檢測,以防止錯誤的信息被寫進去。

在寫入前檢測數據這個功能,我們可以使用BEFORE INSERT 觸發器來實現。

在操作者對 sales 表中的sales_amount 字段進行寫操作時,系統將在寫入(INSERT)前檢查數據是否符合規范。

我們先來看一下,創建觸發器的基本語法

DELIMITER // 
CREATE TRIGGER [觸發器的名字] 
[觸發器執行時機] [觸發器監測的對象] 
ON [表名] FOR EACH ROW [觸發器主體代碼]// 
DELIMITER ;

觸發器的結構包括:

  • DELIMITER //:MySQL 默認分隔符是; 但在觸發器中,我們使用 // 表示觸發器的開始與結束。
  • [觸發器的名字]:這里填寫觸發器的名字
  • [觸發器執行時機]:這里設置觸發器是在關鍵動作執行之前觸發,還是執行之后觸發。
  • [觸發器監測的對象]:觸發器可以監測 INSERTUPDATEDELETE 的操作,當監測的命令對觸發器關聯的表進行操作時,觸發器就被激活了。
  • [表名]:將這個觸發器與數據庫中的表進行關聯,觸發器定義在表上,也附着在表上,如果這個表被刪除了,那么這個觸發器也隨之被刪除。
  • FOR EACH ROW:這句表示只要滿足觸發器觸發條件,觸發器都會被執行,也就是說帶上這個參數后,觸發器將監測每一行對關聯表操作的代碼,一旦符合條件,觸發器就會被觸發。
  • [觸發器主體代碼]:這里是當滿足觸發條件后,被觸發執行的代碼主體。這里可以是一句 SQL 語句,也可以是多行命令。如果是多行命令,那么這些命令要寫在 BEGIN...END 之間。

注:在創建觸發器主體時,還可以使用OLDNEW 來獲取 SQL 執行INSERTUPDATEDELETE 操作前后的寫入數據。這里沒看明白沒關系,我們將會在接下來的實踐中,展開講解。

講到這里,大家看了一大堆雲里霧里的概念,如果沒看懂,也別擔心。接下來進入實踐環節,只要跟着貼代碼看返回結果,很快你就能夠通透理解觸發器了。

現在,我們來創建第一個觸發器,BEFORE INSERT (在執行 insert 之前,執行觸發器)。這個觸發器用於監測操作者在寫入 sales 表中的 sales_amount 值時,這個值是否大於 10000 ,如果大於,那么返回錯誤信息進行報錯。

登錄 MySQL Server 后,我們創建一個觸發器:

DELIMITER //
CREATE TRIGGER validate_sales_amount
BEFORE INSERT
ON sales
FOR EACH ROW
IF NEW.sales_amount>10000 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = "你輸入的銷售總額超過 10000 元。";
END IF//
DELIMITER ;

上面這段代碼中,我們使用IF...THEN...END IF 來創建一個監測 INSERT 語句寫入的值是否在限定的范圍內的觸發器。

這個觸發器的功能時監測 INSERT 在寫入sales_amount 值時,這個新增的(NEW)值是否符合條件( > 10000)。

當操作員錄入一個超過 10000 的數字,會返回如下錯誤信息:

SIGNAL SQLSTATE '45000' 
SET MESSAGE_TEXT = '你輸入的銷售總額超過 10000 元。';

我們來試試看,看看觸發器是否已啟用。

我們向 sales_amount 中插入一條 11000 的值。

Insert into sales(sales_id, customer_id, sales_amount) values('1','1','11000');

輸出結果

ERROR 1644 (45000): 你輸入的銷售總額超過 10000 元。

命令行返回錯誤信息,這就是我們剛剛創建觸發器時,填入的錯誤信息。與我們的設置一致。

下面我們 insert 一個值小於 10000 的數字:

Insert into  sales(sales_id, customer_id, sales_amount) values('1','1','7700');

輸入值為 7700 小於設定的 10000insert 命令執行成功。

Output Query OK, 1 row affected (0.01 sec)

我們調出 sales 表,看看是否插入成功:

Select * from sales;

輸出確認數據在表中:

 

通過這張表,我們可以看到,7700 已經插入到表中。

剛剛我們演示了在執行 insert 命令前,檢測某個值是否符合設定,接着我們來看在執行 insert 之后,使用觸發器將不同的值保存到不同的表中。

  • AFTER INSERT : 在表 A 創建新賬戶后,將創建成功信息自動寫入表 B 中。
  • BEFORE UPDATE :在更新數據前,檢測更新數據是否符合業務邏輯,如不符合返回錯誤信息。
  • AFTER UPDATE :在更新數據后,將操作行為記錄在 log 中
  • BEFORE DELETE :在刪除數據前,檢查是否有關聯數據,如有,停止刪除操作。
  • AFTER DELETE :刪除表 A 信息后,自動刪除表 B 中與表 A 相關聯的信息


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM