有一些非常好的理由可以解釋為什麼資料驗證最好在資料庫層級執行而不是在應用程式層級執行。例如,多個應用程式可以存取相同的資料來源。因此,你可以依賴於資料的一致性和有效性,而不必依賴於在應用程式端套用可能在不同的實作中不一致的驗證邏輯。此外,觸發器是驗證的理想選擇,因為它們可以在插入或更新資料之前執行。觸發器還可以防止在提供錯誤訊息時套用資料庫交易。
在今天的文章中,我們將在 Navicat Premium 撰寫一個觸發器,用於驗證 MySQL 資料庫資料表上的插入作業。
設計觸發器
我們將使用 Sakila 範例資料庫。它包含一些以虛構影碟出租店為主題的相關資料表。在 Navicat Premium 導覽窗格中的資料表如下圖:
我們將把觸發器加入 film 資料表中。如果你在設計器中開啟它,你會看到有幾個索引標籤:
按一下「觸發器」索引標籤可顯示該資料表已定義的一些觸發器。例如,在資料插入 film 資料表時 ins_film 觸發器將電影資訊複製至 film_text 資料表中。這是觸發器的常見工作。
現在我們將加入一個新觸發器,確保使用 original_language_id 插入外國電影。
電影的語言實際儲存在 language 查閱資料表中:
language_id | name | last_update | ||
1 | English | 2006-02-15 05:02:19 | ||
2 | Italian | 2006-02-15 05:02:19 | ||
3 | Japanese | 2006-02-15 05:02:19 | ||
4 | Mandarin | 2006-02-15 05:02:19 | ||
5 | French | 2006-02-15 05:02:19 | ||
6 | German | 2006-02-15 05:02:19 |
除了數值為 1 之外的任何其他 language_id 也應具有 original_language_id。我們的觸發器將檢查 original_language_id 欄中的數值。
- 在 film 資料表的設計檢視中,選取「觸發器」索引標籤,然後按一下「加入觸發器」按鈕。
這將在觸發器表中加入新的一列。 - 為觸發器指定名稱「ins_validate_language」,從「觸發」下拉式功能表中選取「BEFORE」,然後按一下「插入」核取方塊。
- 這是觸發器主體:
BEGIN
IF NEW.language_id != 1 AND NEW.original_language_id IS NULL
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Original language id is required for Foreign language films.';
END IF;
END
這是我們填寫了所有欄位的觸發器:
- 按一下「儲存」按鈕以建立觸發器。
測試觸發器
現在是時候驗證我們的觸發器是否按預期工作。為了測試它,讓我們用一個外語 language_id 加入新的一列到 film 資料表。
- 在編輯器中開啟 film 資料表。
- 巡覽至最後一列。
- 選取「表單檢視」,然後按一下加號(+)按鈕加入新列:
- 在表單中,你只需輸入 title 和 language_id,所有其他欄位都具有預設值或不是必需的。
- 按一下「加入」(勾號)按鈕時,你應該看到我們的錯誤消息:
總結
觸發器是資料驗證的理想選擇,因為它們可以在插入或更新資料之前執行。我們透過在 Navicat Premium 中撰寫觸發器,了解如何將觸發器用於驗證目的。