MySQL中觸發器的使用

觸發器:

觸發器的使用場景以及相應版本:

觸發器可使用的MySQL版本:

  • 版本:MySQL5以上

使用場景例子:

  1. 每當增長一個顧客到某個數據庫表時,都檢查其電話號碼格式是否正確,州的縮寫是否爲大寫
  2. 每當訂購一個產品時,都從庫存數量中減去訂購的數量
  3. 不管什麼時候刪除一行,都在某個存檔表中保留一個副本

即:在某個表發生更改時自動處理。html

如遇到觸發器報錯「Not allowed to return a result set from a trigger」;請劃到最後看詳解;mysql

觸發器的使用:

建立基本的觸發器:sql

CREATE TRIGGER newproduct AFTER INSERT on products FOR EACH ROW
BEGIN
 DECLARE msg VARCHAR(100);
 SET msg = "products added";
 SIGNAL SQLSTATE 'HY000' SET message_text = msg;
 
END

結果:數據庫

INSERT INTO products VALUES('demo2','1003','xiaoguo','66.6','hello world')
> 1644 - products added
> 時間: 0.035s

解釋:.net

首先建立一個觸發器:code

#newproduct  觸發器的名字
CREATE TRIGGER newproduct

觸發的時機:htm

BEFORE:觸發器在觸發他們的語句以前觸發blog

AFTER:觸發器在觸發他們的語句完成後觸發事件

在這裏咱們使用的after;也就是在插入結束後觸發條件;get

DECLARE msg VARCHAR(100);

注意:declare語句是在複合語句中聲明變量的指令;若是不聲明msg,執行語句時,MySQL報錯;

SIGNAL SQLSTATE 'HY000' SET message_text = msg;

若是該SIGNAL語句指示特定SQLSTATE值,則該值用於表示指定的條件

"HY000」被稱爲「通常錯誤":

若是命令出現通常錯誤,則會觸發後面的message中的消息;

注:該語句只是我的理解,也是隻知其一;不知其二,若是有更好的解釋,歡迎留言。

觸發的條件以BEGIN開始,END結束。

觸發事件:

  1. insert
  2. update
  3. delete

刪除觸發器:

-- 刪除觸發器
DROP TRIGGER newproduct;

INSERT觸發器:

insert觸發器在insert語句執行以前或者以後執行,須要注意如下幾點:

  1. 在insert觸發器代碼內。能夠引用一個名爲NEW的虛擬表,訪問被插入的行;
  2. 在before insert觸發器中,NEW中的值也能夠被更新(容許更改被插入的值)
  3. 對於AUTO_INCREMENT列,NEW在insert執行以前包含0,在insert執行以後包含新的自動生成值

例子:插入一個新的訂單時,生成一個新的訂單號保存到order_num

CREATE TRIGGER neworder AFTER INSERT ON orders for EACH ROW
 SELECT NEW.order_num into @ee;

insert INTO orders(order_date,cust_id) VALUES(NOW(),10001);
SELECT @ee as num;

drop TRIGGER neworder;

解釋:

建立一個neworder的觸發器,在插入以後執行,且對每一個插入行執行,在insert中有一個與orders表一摸同樣的虛表,用NEW 表示;

SELECT NEW.order_num into @a;

在虛表中找到咱們插入的數據的編號,將標號保存在a變量中;

檢測:

insert INTO orders(order_date,cust_id) VALUES(NOW(),10001);
SELECT @ee as num;

插入數據,輸出插入數據的編號

刪除:

drop TRIGGER neworder;

刪除觸發器。

例二:

在COURSE表上建立觸發器,檢查插入時是否出現課程名相同的記錄,如有則不操做。

CREATE TRIGGER trg_course_in 
BEFORE INSERT ON course
FOR EACH ROW
BEGIN
        DECLARE msg VARCHAR(100);  
        IF EXISTS (SELECT * FROM  course where cname=NEW.cname)   THEN 
            SET msg='不能輸入相同名稱的課程'; 
            SIGNAL SQLSTATE 'HY000' SET message_text = msg; 
        END IF; 
    
END

例三:向student表中插入信息時,檢查ssex的值必須爲男或女。

CREATE TRIGGER trg_ssex AFTER INSERT on student FOR EACH ROW
BEGIN
 DECLARE msg VARCHAR(100);
 IF(NEW.ssex not in('男','女')) THEN
 	SET msg ='性別必須爲男或女'; 
 	SIGNAL SQLSTATE 'HY000' SET message_text = msg;
 END IF
END

UPDATE觸發器:

  1. 在update觸發器的代碼中,能夠引用一個名爲OLD的虛擬表訪問之前的值,即:update未執行前的值,還能夠引用一個名爲NEW的虛擬表訪問新更新的值;
  2. 在before update觸發器中,NEW中的值可能也被更新(容許修改將要用於update語句中的值);
  3. OLD中的值所有隻讀,不能更新。

例一:保證州名縮寫爲大寫

CREATE TRIGGER UPDATEevendor BEFORE UPDATE on vendors
FOR EACH ROW SET new.vend_state =UPPER(new.vend_state);

UPDATE vendors SET vend_state='hw' where vend_id='1001';
DROP TRIGGER UPDATEevendor;

注:upper:將文本轉換爲大寫:

例二:不容許修改student表中的學號sno,若是修改該列則顯示錯誤信息並取消操做。

CREATE TRIGGER trg_student_updateSno BEFORE UPDATE
FOR EACH ROW
BEGIN
 DECLARE msg VARCHAR(100);  
 IF NEW.sno <> OLD.sno THEN 
 	SET msg='不容許修改sno'; 
    SIGNAL SQLSTATE 'HY000' SET message_text = msg;  
 END IF; 
END

DELETE觸發器:

在DELETE觸發器在delete語句執行以前或以後執行:

  1. 在delete觸發器代碼內,能夠引用OLD的虛擬表,訪問被刪除的行;
  2. OLD中的值所有都是隻讀,不能更新

例子:

使用old保存將要被刪除的行到一個存檔表中

首先先建立一個與orders類似的表:

CREATE TABLE archive_orders LIKE orders;
-- 建立一個刪除的觸發器
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

解釋:

在刪除order表中行中信息時,將刪除的信息保存到archive_orders中;

刪除原表中一行:

DELETE FROM orders WHERE order_num='20014';

查看效果:

SELECT * FROM archive_orders;

結束:

注:若是遇到觸發器報錯「Not allowed to return a result set from a trigger」

  1. 緣由:由於從MySQL5之後不支持觸發器返回結果集
  2. 解決方法:在後面語句後面添加 into @變量名
  3. 取數據:select @變量名

詳細解釋:https://www.programmersought.com/article/3237975256/

建立用戶變量:https://blog.csdn.net/JesseYoung/article/details/40779631

感謝各位看到最後!

相關文章
相關標籤/搜索