MySQL - 更新前觸發器

MySQL更新前觸發器介紹

你好,有志於數據庫的熱心者!今天,我們將要深入MySQL更新前觸發器的精彩世界。別擔心你對編程還是新手;我會成為你這次旅程中的友好導遊,逐步解釋一切。在本教程結束時,你將能像專業人士一樣創建觸發器!

MySQL - Before Update Trigger

什麼是更新前觸發器?

想像你是一名豪華藝術画廊的安全警衛。你的工作是檢查人們的包,在他們進入展覽室之前。這正是MySQL中的更新前觸發器所做的!它是一種特殊類型的程序,在數據庫中的記錄即將被更新之前自動運行。它就像數據庫的私人安全警衛,在變化發生之前確保一切正常。

MySQL更新前觸發器語法

讓我們從更新前觸發器的基本結構開始。別擔心起初看起來可能有些令人生畏;我們會一起分解它!

CREATE TRIGGER trigger_name
BEFORE UPDATE ON table_name
FOR EACH ROW
BEGIN
-- 你的觸發器代碼寫在這裡
END;

讓我們解釋這個魔法咒語:

  1. CREATE TRIGGER trigger_name:這裡你給你的觸發器命名。明智地選擇!
  2. BEFORE UPDATE:這告訴MySQL在更新發生之前運行觸發器。
  3. ON table_name:指定你想保護的表。
  4. FOR EACH ROW:這意味著對於被更新的每一行,觸發器都會運行。
  5. BEGINEND:這些關鍵字包裹著你的觸發器的實際代碼。

一個簡單的例子

讓我們創建一個簡單的觸發器,記錄當有人嘗試更改員工薪資時。我們將使用一個名為 employees 的表,並創建一個名為 salary_changes 的日誌表。

-- 首先,讓我們創建我們的表
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
salary DECIMAL(10, 2)
);

CREATE TABLE salary_changes (
id INT AUTO_INCREMENT PRIMARY KEY,
employee_id INT,
old_salary DECIMAL(10, 2),
new_salary DECIMAL(10, 2),
change_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 現在,讓我們創建我們的觸發器
DELIMITER //
CREATE TRIGGER before_salary_update
BEFORE UPDATE ON employees
FOR EACH ROW
BEGIN
IF OLD.salary != NEW.salary THEN
INSERT INTO salary_changes (employee_id, old_salary, new_salary)
VALUES (OLD.id, OLD.salary, NEW.salary);
END IF;
END;//
DELIMITER ;

讓我們分解這個:

  1. 我們創建兩個表:employees 存储員工信息,salary_changes 日誌薪資更新。
  2. 我們的觸發器名為 before_salary_update
  3. 在觸發器內部,我們檢查薪資是否實際上有變化 (IF OLD.salary != NEW.salary)。
  4. 如果有變化,我們將插入一條新記錄到我們的 salary_changes 表。
  5. OLD 指的是當前值,NEW 指的是即將設置的新值。

在客戶端程序中使用觸發器

現在,讓我們看看如何在現實世界場景中使用這個觸發器。想像你正在為一家小型公司构建一個薪酬系統。你希望確保所有薪資變化都適當記錄,以便於審計。

以下是一個簡單的Python腚本,用於連接到你的MySQL數據庫並更新員工的薪資:

import mysql.connector

# 連接到數據庫
db = mysql.connector.connect(
host="localhost",
user="your_username",
password="your_password",
database="your_database"
)

cursor = db.cursor()

# 更新員工薪資的函數
def update_salary(employee_id, new_salary):
sql = "UPDATE employees SET salary = %s WHERE id = %s"
values = (new_salary, employee_id)
cursor.execute(sql, values)
db.commit()
print(f"員工 {employee_id} 的薪資已更新")

# 更新一個員工的薪資
update_salary(1, 55000)

# 關閉連接
db.close()

當你運行這個腚本時:

  1. 它會連接到你的MySQL數據庫。
  2. update_salary 函數會更新指定員工的薪資。
  3. UPDATE 語句被執行時,我們的 before_salary_update 觸發器會自動觸發。
  4. 觸發器檢查薪資是否變化,並在 salary_changes 表中記錄變化。
  5. 所有這些都是在實際更新 employees 表之前發生的。

檢查我們的觸發器是否工作

運行腚本後,你可以通過查詢 salary_changes 表來驗證觸發器是否工作:

SELECT * FROM salary_changes;

你應該會看到一個新條目,顯示員工1的舊薪資和新年資。

高級觸發器技巧

現在你已经掌握了基礎知識,讓我們看看一些可以使用更新前觸發器的高級技巧。

驗證數據

觸發器可以用來強制執行業務規則。例如,我們說我們不允許薪資減少:

DELIMITER //
CREATE TRIGGER prevent_salary_decrease
BEFORE UPDATE ON employees
FOR EACH ROW
BEGIN
IF NEW.salary < OLD.salary THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '薪資不能減少';
END IF;
END;//
DELIMITER ;

如果有人試圖降低員工的薪資,這個觸發器會抛出一個錯誤。

修改 NEW 值

你也可以在更新之前使用觸發器來修改數據:

DELIMITER //
CREATE TRIGGER round_salary
BEFORE UPDATE ON employees
FOR EACH ROW
BEGIN
SET NEW.salary = ROUND(NEW.salary, -3);
END;//
DELIMITER ;

這個觸發器會在更新發生之前將新薪資四舍五入到最接近的千位。

最佳實踐和考慮

  1. 保持觸發器簡單:複雜的觸發器代碼會使調試變得困難。
  2. 注意性能:觸發器對於每一行受影響的數據都會運行,因此它可能會減慢大型表的操作。
  3. 避免無窮循環:小心不要創建可能無限觸發自己的觸發器。
  4. 文檔化你的觸發器:總是評論你的觸發器代碼,並維護有關觸發器存在及其功能的文檔。

結論

恭喜你!你剛剛開始了一段進入MySQL更新前觸發器世界的精彩旅程。這些強大的工具讓你能在數據庫操作中添加一層額外的控制和自動化。記住,能力越大,責任越大——謹慎使用你的觸發器!

在你繼續你的數據庫冒險時,你會發現無數創造性的方法來使用觸發器解決現實世界問題。持續練習,保持好奇心,並不怕嘗試。誰知道呢?你可能會成為你團隊中的下一個數據庫巫師!

開心觸發,願你的查詢總是返回你期望的結果!

Credits: Image by storyset