利用MySQL觸發器實現check和assertion

MySQL雖然輸入check語句不會報錯,但是實際上並沒有check的功能。但是MySQL 依然可以利用觸發器來實現相應功能。
本文將根據兩個例子簡要闡述MySQL實現checkassertion的思路。

MySQL觸發器 官方文檔 MySQL Signal 官方文檔

注意

signal異常處理功能在MySQL5.5版本以後纔出現。之前的版本可以選擇對相應值進行操作而不是報錯。

下文測試所用數據庫版本爲Server version: 10.1.21-MariaDB Source distribution

check實現

例子1是希望能夠對插入表項有約束,例如年齡不能超過60,若大於60則報錯,拒絕插入。

對於其他的支持check的數據庫,可以用以下語句來實現:

alter table emp add constraint c_age check(age<60);

而利用觸發器,則可以寫如下語句

delimiter //
create trigger age before insert 
on emp for each row
begin
    declare msg varchar(200); 
    if (new.age > 60) then  
        set msg = "Age is above 60. Cannot insert.";    
            signal sqlstate 'HY000' SET message_text = msg;    
    end if;
end //
delimiter ;

(最後記得恢復;爲結束標誌) 將其保存至1.sql,測試其功能

MariaDB [book5]> source path/to/it/1.sql
Query OK, 0 rows affected (0.03 sec)

MariaDB [book5]> insert into emp values(3,'bobo',61,'softeng',10000,1);
ERROR 1644 (HY000): Age is above 60. Cannot insert.

assertion實現

例子2 是希望限制兩個表的元組總數不能超過5。

支持assertion的數據庫可以用以下語句實現:

create assertion asse_count
check(50>=select count(*) from 
(select * from male union select * from female) as guest);

利用觸發器也可實現這個功能。

delimiter //
create trigger count_check_male before insert 
on male for each row
begin
    declare msg varchar(200);
    declare count int;
    set count = (select count(*) from male);
    set count = count + (select count(*) from female);
    if (count >= 5) then  
        set msg = "The count of guest is above 5.";    
        signal sqlstate 'HY000' SET message_text = msg;    
    end if;
end //
create trigger count_check_female before insert 
on female for each row
begin
    declare msg varchar(200);
    declare count int;
    set count = (select count(*) from male);
    set count = count + (select count(*) from female);
    if (count >= 5) then  
        set msg = "The count of guest is above 5.";    
        signal sqlstate 'HY000' SET message_text = msg;    
    end if;
end //
delimiter ;

由於是插入之前進行處理,這裏要注意爲count >= 5

在利用聚集函數結果對變量進行賦值時記得加括號。

測試觸發器功能:

MariaDB [book5]> select count(*) from female;
+----------+
| count(*) |
+----------+
|        3 |
+----------+
1 row in set (0.00 sec)

MariaDB [book5]> select count(*) from male;
+----------+
| count(*) |
+----------+
|        2 |
+----------+
1 row in set (0.00 sec)

MariaDB [book5]> insert into male values(3,"test");
ERROR 1644 (HY000): The count of guest is above 5.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章