您好,登錄后才能下訂單哦!
這篇文章主要介紹“MySQL觸發(fā)器怎么創(chuàng)建和使用”,在日常操作中,相信很多人在MySQL觸發(fā)器怎么創(chuàng)建和使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對(duì)大家解答”MySQL觸發(fā)器怎么創(chuàng)建和使用”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
在實(shí)際開發(fā)中,我們經(jīng)常會(huì)遇到這樣的情況:有 2 個(gè)或者多個(gè)相互關(guān)聯(lián)的表,如 商品信息 和 庫存信息 分 別存放在 2 個(gè)不同的數(shù)據(jù)表中,我們?cè)谔砑右粭l新商品記錄的時(shí)候,為了保證數(shù)據(jù)的完整性,必須同時(shí) 在庫存表中添加一條庫存記錄。 這樣一來,我們就必須把這兩個(gè)關(guān)聯(lián)的操作步驟寫到程序里面,而且要用 事務(wù) 包裹起來,確保這兩個(gè)操 作成為一個(gè) 原子操作 ,要么全部執(zhí)行,要么全部不執(zhí)行。
要是遇到特殊情況,可能還需要對(duì)數(shù)據(jù)進(jìn)行手 動(dòng)維護(hù),這樣就很 容易忘記其中的一步 ,導(dǎo)致數(shù)據(jù)缺失。 這個(gè)時(shí)候,咱們可以使用觸發(fā)器。你可以創(chuàng)建一個(gè)觸發(fā)器,讓商品信息數(shù)據(jù)的插入操作自動(dòng)觸發(fā)庫存數(shù) 據(jù)的插入操作。這樣一來,就不用擔(dān)心因?yàn)橥浱砑訋齑鏀?shù)據(jù)而導(dǎo)致的數(shù)據(jù)缺失了。
MySQL從 5 . 0 . 2 版本開始支持觸發(fā)器。 MySQL的觸發(fā)器和存儲(chǔ)過程一樣,都是嵌入到MySQL服務(wù)器的一 段程序。 觸發(fā)器是由 事件來觸發(fā) 某個(gè)操作,這些事件包括 INSERT 、 UPDATE 、 DELETE 事件。
所謂事件就是指 用戶的動(dòng)作或者觸發(fā)某項(xiàng)行為。如果定義了觸發(fā)程序,當(dāng)數(shù)據(jù)庫執(zhí)行這些語句時(shí)候,就相當(dāng)于事件發(fā)生 了,就會(huì) 自動(dòng) 激發(fā)觸發(fā)器執(zhí)行相應(yīng)的操作。 當(dāng)對(duì)數(shù)據(jù)表中的數(shù)據(jù)執(zhí)行插入、更新和刪除操作,需要自動(dòng)執(zhí)行一些數(shù)據(jù)庫邏輯時(shí),可以使用觸發(fā)器來 實(shí)現(xiàn)。
創(chuàng)建觸發(fā)器語法
CREATE TRIGGER 觸發(fā)器名稱 {BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON 表名 FOR EACH ROW 觸發(fā)器執(zhí)行的語句塊;
說明:
表名 :表示觸發(fā)器監(jiān)控的對(duì)象。
BEFORE | AFTER :表示觸發(fā)的時(shí)間。 BEFORE 表示在事件之前觸發(fā); AFTER 表示在事件之后觸發(fā)。
INSERT | UPDATE | DELETE :表示觸發(fā)的事件。
INSERT 表示插入記錄時(shí)觸發(fā);
UPDATE 表示更新記錄時(shí)觸發(fā);
DELETE 表示刪除記錄時(shí)觸發(fā)。
創(chuàng)建倆張表
CREATE TABLE test_trigge r ( id INT PRIMARY KEY AUTO_INCREMENT , t_note VARCHAR ( 30 ) ) ; CREATE TABLE test_trigger_log ( id INT PRIMARY KEY AUTO_INCREMENT , t_log VARCHAR ( 30 ) ) ;
創(chuàng)建觸發(fā)器
DELIMITER / / CREATE TRIGGER befo_re_insert BEFORE INSERT ON test_trigger FOR EACH ROW BEGIN INSERT INTO test_trigger_log ( t_log ) VALUES ( ' befo re_inse rt ' ) ; END / / DELIMITER ;
向test_trigger數(shù)據(jù)表中插入數(shù)據(jù)
INSERT INTO test_trigger (t_note) VALUES ('測試 BEFORE INSERT 觸發(fā)器');
查看test_trigger_log數(shù)據(jù)表中的數(shù)據(jù)
SELECT * FROM test_trigger_log
創(chuàng)建觸發(fā)器
DELIMITER / / CREATE TRIGGER after_insert AFTER INSERT ON test_trigger FOR EACH ROW BEGIN INSERT INTO test_trigger_log ( t_log ) VALUES ( ' after_insert ' ) ; END / / DELIMITER ;
向test_trigger數(shù)據(jù)表中插入數(shù)據(jù)。
INSERT INTO test_trigger (t_note) VALUES ('測試 AFTER INSERT 觸發(fā)器');
查看test_trigger_log數(shù)據(jù)表中的數(shù)據(jù)
SELECT * FROM test_trigger_log
定義觸發(fā)器“salary_check_trigger”,基于員工表“employees”的INSERT事件,在INSERT之前檢查將要添加的新員工薪資是否大于他領(lǐng)導(dǎo)的薪資,如果大于領(lǐng)導(dǎo)薪資,則報(bào)sqlstate_value為'HY000'的錯(cuò)誤,從而使得添加失敗。
DELIMITER // CREATE TRIGGER salary_check_trigger BEFORE INSERT ON employees FOR EACH ROW BEGIN DECLARE mgrsalary DOUBLE; SELECT salary INTO mgrsalary FROM employees WHERE employee_id = NEW.manager_id; IF NEW.salary > mgrsalary THEN SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = '薪資高于領(lǐng)導(dǎo)薪資錯(cuò)誤'; END IF; END // DELIMITER ;
上面觸發(fā)器聲明過程中的NEW關(guān)鍵字代表INSERT添加語句的新記錄。
方式1:查看當(dāng)前數(shù)據(jù)庫的所有觸發(fā)器的定義
SHOW TRIGGERS
方式2:查看當(dāng)前數(shù)據(jù)庫中某個(gè)觸發(fā)器的定義方式
SHOW CREATE TRIGGER 觸發(fā)器名
方式3:從系統(tǒng)庫information_schema的TRIGGERS表中查詢“salary_check_trigger”觸發(fā)器的信息。
SELECT * FROM information_schema.TRIGGERS;
刪除觸發(fā)器
DROP TRIGGER IF EXISTS 觸發(fā)器名稱
1、觸發(fā)器可以確保數(shù)據(jù)的完整性。
假設(shè)我們用 進(jìn)貨單頭表 (demo.importhead)來保存進(jìn)貨單的總體信息,包括進(jìn)貨單編號(hào)、供貨商編號(hào)、倉庫編號(hào)、總計(jì)進(jìn)貨數(shù)量、總計(jì)進(jìn)貨金額和驗(yàn)收日期。
用 進(jìn)貨單明細(xì)表 (demo.importdetails)來保存進(jìn)貨商品的明細(xì),包括進(jìn)貨單編號(hào)、商品編號(hào)、進(jìn)貨數(shù)
量、進(jìn)貨價(jià)格和進(jìn)貨金額額就不等于進(jìn)貨單明細(xì)表中數(shù)量合計(jì)和金額合計(jì)了,這就是數(shù)據(jù)不一致。
為了解決這個(gè)問題,我們就可以使用觸發(fā)器,規(guī)定每當(dāng)進(jìn)貨單明細(xì)表有數(shù)據(jù)插入、修改和刪除的操作
時(shí),自動(dòng)觸發(fā) 2 步操作:
1)重新計(jì)算進(jìn)貨單明細(xì)表中的數(shù)量合計(jì)和金額合計(jì);
2)用第一步中計(jì)算出來的值更新進(jìn)貨單頭表中的合計(jì)數(shù)量與合計(jì)金額。
這樣一來,進(jìn)貨單頭表中的合計(jì)數(shù)量與合計(jì)金額的值,就始終與進(jìn)貨單明細(xì)表中計(jì)算出來的合計(jì)數(shù)量與
合計(jì)金額的值相同,數(shù)據(jù)就是一致的,不會(huì)互相矛盾。
2、觸發(fā)器可以幫助我們記錄操作日志。
利用觸發(fā)器,可以具體記錄什么時(shí)間發(fā)生了什么。比如,記錄修改會(huì)員儲(chǔ)值金額的觸發(fā)器,就是一個(gè)很
好的例子。這對(duì)我們還原操作執(zhí)行時(shí)的具體場景,更好地定位問題原因很有幫助。
3、觸發(fā)器還可以用在操作數(shù)據(jù)前,對(duì)數(shù)據(jù)進(jìn)行合法性檢查。
比如,超市進(jìn)貨的時(shí)候,需要庫管錄入進(jìn)貨價(jià)格。但是,人為操作很容易犯錯(cuò)誤,比如說在錄入數(shù)量的
時(shí)候,把條形碼掃進(jìn)去了;錄入金額的時(shí)候,看串了行,錄入的價(jià)格遠(yuǎn)超售價(jià),導(dǎo)致賬面上的巨虧......
這些都可以通過觸發(fā)器,在實(shí)際插入或者更新操作之前,對(duì)相應(yīng)的數(shù)據(jù)進(jìn)行檢查,及時(shí)提示錯(cuò)誤,防止
錯(cuò)誤數(shù)據(jù)進(jìn)入系統(tǒng)。
1、觸發(fā)器最大的一個(gè)問題就是可讀性差。
因?yàn)橛|發(fā)器存儲(chǔ)在數(shù)據(jù)庫中,并且由事件驅(qū)動(dòng),這就意味著觸發(fā)器有可能 不受應(yīng)用層的控制 。這對(duì)系統(tǒng)維護(hù)是非常有挑戰(zhàn)的。
比如,創(chuàng)建觸發(fā)器用于修改會(huì)員儲(chǔ)值操作。如果觸發(fā)器中的操作出了問題,會(huì)導(dǎo)致會(huì)員儲(chǔ)值金額更新失敗。我用下面的代碼演示一下
結(jié)果顯示,系統(tǒng)提示錯(cuò)誤,字段“aa”不存在。
這是因?yàn)?,觸發(fā)器中的數(shù)據(jù)插入操作多了一個(gè)字段,系統(tǒng)提示錯(cuò)誤。可是,如果你不了解這個(gè)觸發(fā)器,很可能會(huì)認(rèn)為是更新語句本身的問題,或者是會(huì)員信息表的結(jié)構(gòu)出了問題。說不定你還會(huì)給會(huì)員信息表添加一個(gè)叫“aa”的字段,試圖解決這個(gè)問題,結(jié)果只能是白費(fèi)力。
2、相關(guān)數(shù)據(jù)的變更,可能會(huì)導(dǎo)致觸發(fā)器出錯(cuò)。
特別是數(shù)據(jù)表結(jié)構(gòu)的變更,都可能會(huì)導(dǎo)致觸發(fā)器出錯(cuò),進(jìn)而影響數(shù)據(jù)操作的正常運(yùn)行。這些都會(huì)由于觸發(fā)器本身的隱蔽性,影響到應(yīng)用中錯(cuò)誤原因排查的效率。
注意,如果在子表中定義了外鍵約束,并且外鍵指定了ON UPDATE/DELETE CASCADE/SET NULL子句,此時(shí)修改父表被引用的鍵值或刪除父表被引用的記錄行時(shí),也會(huì)引起子表的修改和刪除操作,此時(shí)基于子表的UPDATE和DELETE語句定義的觸發(fā)器并不會(huì)被激活。
例如:基于子表員工表(t_employee)的DELETE語句定義了觸發(fā)器t1,而子表的部門編號(hào)(did)字段定義了外鍵約束引用了父表部門表(t_department)的主鍵列部門編號(hào)(did),并且該外鍵加了“ONDELETE SET NULL”子句,那么如果此時(shí)刪除父表部門表(t_department)在子表員工表(t_employee)
到此,關(guān)于“MySQL觸發(fā)器怎么創(chuàng)建和使用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。