欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mysql觸發(fā)器trigger實(shí)例詳解

 更新時(shí)間:2021年03月17日 00:13:18   作者:周伯通  
MySQL好像從5.0.2版本就開始支持觸發(fā)器的功能了,本次博客就來介紹一下觸發(fā)器,首先還是談下概念性的東西吧,需要的朋友可以參考下

MySQL好像從5.0.2版本就開始支持觸發(fā)器的功能了,本次博客就來介紹一下觸發(fā)器,首先還是談下概念性的東西吧:

什么是觸發(fā)器

觸發(fā)器是與表有關(guān)的數(shù)據(jù)庫對(duì)象,在滿足定義條件時(shí)觸發(fā),并執(zhí)行觸發(fā)器中定義的語句集合。觸發(fā)器的這種特性可以協(xié)助應(yīng)用在數(shù)據(jù)庫端確保數(shù)據(jù)的完整性。

舉個(gè)例子,比如你現(xiàn)在有兩個(gè)表【用戶表】和【日志表】,當(dāng)一個(gè)用戶被創(chuàng)建的時(shí)候,就需要在日志表中插入創(chuàng)建的log日志,如果在不使用觸發(fā)器的情況下,你需要編寫程序語言邏輯才能實(shí)現(xiàn),但是如果你定義了一個(gè)觸發(fā)器,觸發(fā)器的作用就是當(dāng)你在用戶表中插入一條數(shù)據(jù)的之后幫你在日志表中插入一條日志信息。當(dāng)然觸發(fā)器并不是只能進(jìn)行插入操作,還能執(zhí)行修改,刪除。

創(chuàng)建觸發(fā)器

創(chuàng)建觸發(fā)器的語法如下:

CREATE TRIGGER trigger_name trigger_time trigger_event ON tb_name FOR EACH ROW trigger_stmt
trigger_name:觸發(fā)器的名稱
tirgger_time:觸發(fā)時(shí)機(jī),為BEFORE或者AFTER
trigger_event:觸發(fā)事件,為INSERT、DELETE或者UPDATE
tb_name:表示建立觸發(fā)器的表明,就是在哪張表上建立觸發(fā)器
trigger_stmt:觸發(fā)器的程序體,可以是一條SQL語句或者是用BEGIN和END包含的多條語句
所以可以說MySQL創(chuàng)建以下六種觸發(fā)器:
BEFORE INSERT,BEFORE DELETE,BEFORE UPDATE
AFTER INSERT,AFTER DELETE,AFTER UPDATE

其中,觸發(fā)器名參數(shù)指要?jiǎng)?chuàng)建的觸發(fā)器的名字

BEFORE和AFTER參數(shù)指定了觸發(fā)執(zhí)行的時(shí)間,在事件之前或是之后

FOR EACH ROW表示任何一條記錄上的操作滿足觸發(fā)事件都會(huì)觸發(fā)該觸發(fā)器

創(chuàng)建有多個(gè)執(zhí)行語句的觸發(fā)器

CREATE TRIGGER 觸發(fā)器名 BEFORE|AFTER 觸發(fā)事件
ON 表名 FOR EACH ROW
BEGIN
  執(zhí)行語句列表
END

其中,BEGIN與END之間的執(zhí)行語句列表參數(shù)表示需要執(zhí)行的多個(gè)語句,不同語句用分號(hào)隔開

tips:一般情況下,mysql默認(rèn)是以 ; 作為結(jié)束執(zhí)行語句,與觸發(fā)器中需要的分行起沖突

     為解決此問題可用DELIMITER,如:DELIMITER ||,可以將結(jié)束符號(hào)變成||

     當(dāng)觸發(fā)器創(chuàng)建完成后,可以用DELIMITER ;來將結(jié)束符號(hào)變成;

mysql> DELIMITER ||
mysql> CREATE TRIGGER demo BEFORE DELETE
  -> ON users FOR EACH ROW
  -> BEGIN
  -> INSERT INTO logs VALUES(NOW());
  -> INSERT INTO logs VALUES(NOW());
  -> END
  -> ||
Query OK, 0 rows affected (0.06 sec)

mysql> DELIMITER ;

上面的語句中,開頭將結(jié)束符號(hào)定義為||,中間定義一個(gè)觸發(fā)器,一旦有滿足條件的刪除操作

就會(huì)執(zhí)行BEGIN和END中的語句,接著使用||結(jié)束

最后使用DELIMITER ; 將結(jié)束符號(hào)還原

tigger_event:

load data語句是將文件的內(nèi)容插入到表中,相當(dāng)于是insert語句,而replace語句在一般的情況下和insert差不多,但是如果表中存在primary 或者unique索引的時(shí)候,如果插入的數(shù)據(jù)和原來的primary key或者unique相同的時(shí)候,會(huì)刪除原來的數(shù)據(jù),然后增加一條新的數(shù)據(jù),所以有的時(shí)候執(zhí)行一條replace語句相當(dāng)于執(zhí)行了一條delete和insert語句。

觸發(fā)器可以是一條SQL語句,也可以是多條SQL代碼塊,那如何創(chuàng)建呢?

DELIMITER $ #將語句的分隔符改為$
BEGIN
sql1;
sql2;
...
sqln
END $
DELIMITER ; #將語句的分隔符改回原來的分號(hào)";"
在BEGIN...END語句中也可以定義變量,但是只能在BEGIN...END內(nèi)部使用:
DECLARE var_name var_type [DEFAULT value] #定義變量,可指定默認(rèn)值
SET var_name = value #給變量賦值
NEW和OLD的使用:

 根據(jù)以上的表格,可以使用一下格式來使用相應(yīng)的數(shù)據(jù):

NEW.columnname:新增行的某列數(shù)據(jù)
OLD.columnname:刪除行的某列數(shù)據(jù)
說了這么多現(xiàn)在我們來創(chuàng)建一個(gè)觸發(fā)器吧!

現(xiàn)在有表如下:

用戶users表

CREATE TABLE `users` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
 `add_time` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `name` (`name`(250)) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=1000001 DEFAULT CHARSET=latin1;

日志logs表:

CREATE TABLE `logs` (
 `Id` int(11) NOT NULL AUTO_INCREMENT,
 `log` varchar(255) DEFAULT NULL COMMENT '日志說明',
 PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='日志表';

需求是:當(dāng)在users中插入一條數(shù)據(jù),就會(huì)在logs中生成一條日志信息。

創(chuàng)建觸發(fā)器:

DELIMITER $
CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROW
BEGIN
DECLARE s1 VARCHAR(40)character set utf8;
DECLARE s2 VARCHAR(20) character set utf8;#后面發(fā)現(xiàn)中文字符編碼出現(xiàn)亂碼,這里設(shè)置字符集
SET s2 = " is created";
SET s1 = CONCAT(NEW.name,s2);   #函數(shù)CONCAT可以將字符串連接
INSERT INTO logs(log) values(s1);
END $
DELIMITER ;

這里我用的navicat: 

查看觸發(fā)器SHOW TRIGGERS語句查看觸發(fā)器信息

Tip:

上面我用的navicat直接創(chuàng)建,如果大家用的mysql front,name這里會(huì)有個(gè)區(qū)別,我們刪除剛才的觸發(fā)器,在Mysql front中測(cè)試

drop trigger user_log;#刪除觸發(fā)器

打開Mysql Front:

 

mysql front在編譯sql時(shí),不用定義結(jié)尾分隔符,修改后的sql直接這樣既可:

#DELIMITER $
CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROW
BEGIN
DECLARE s1 VARCHAR(40)character set utf8;
DECLARE s2 VARCHAR(20) character set utf8;
SET s2 = " is created";
SET s1 = CONCAT(NEW.name,s2);   #函數(shù)CONCAT可以將字符串連接
INSERT INTO logs(log) values(s1);
END #$
#DELIMITER ;

這里再啰嗦幾句:

tips:SHOW TRIGGERS語句無法查詢指定的觸發(fā)器

在triggers表中查看觸發(fā)器信息

SELECT * FROM information_schema.triggers;

結(jié)果顯示了所有觸發(fā)器的詳細(xì)信息,同時(shí),該方法可以查詢制定觸發(fā)器的詳細(xì)信息

SELECT * FROM information_schema.triggers WHERE TRIGGER_NAME='user_log';

tips:所有觸發(fā)器信息都存儲(chǔ)在information_schema數(shù)據(jù)庫下的triggers表中

     可以使用SELECT語句查詢,如果觸發(fā)器信息過多,最好通過TRIGGER_NAME字段指定查詢

回到上面,我們創(chuàng)建好了觸發(fā)器,繼續(xù)在users中插入數(shù)據(jù)并查看數(shù)據(jù):

insert into users(name,add_time) values('周伯通',now());

好吧,我們?cè)賮聿榭匆幌耹ogs表吧!

通過上面的例子,可以看到只需要在users中插入用戶的信息,日志會(huì)自動(dòng)記錄到logs表中,這也許就是觸發(fā)器給我?guī)淼谋憬莅桑?nbsp;

限制和注意事項(xiàng)

觸發(fā)器會(huì)有以下兩種限制:

1.觸發(fā)程序不能調(diào)用將數(shù)據(jù)返回客戶端的存儲(chǔ)程序,也不能使用采用CALL語句的動(dòng)態(tài)SQL語句,但是允許存儲(chǔ)程序通過參數(shù)將數(shù)據(jù)返回觸發(fā)程序,也就是存儲(chǔ)過程或者函數(shù)通過OUT或者INOUT類型的參數(shù)將數(shù)據(jù)返回觸發(fā)器是可以的,但是不能調(diào)用直接返回?cái)?shù)據(jù)的過程。

2.不能再觸發(fā)器中使用以顯示或隱式方式開始或結(jié)束事務(wù)的語句,如START TRANS-ACTION,COMMIT或ROLLBACK。

注意事項(xiàng):MySQL的觸發(fā)器是按照BEFORE觸發(fā)器、行操作、AFTER觸發(fā)器的順序執(zhí)行的,其中任何一步發(fā)生錯(cuò)誤都不會(huì)繼續(xù)執(zhí)行剩下的操作,如果對(duì)事務(wù)表進(jìn)行的操作,如果出現(xiàn)錯(cuò)誤,那么將會(huì)被回滾,如果是對(duì)非事務(wù)表進(jìn)行操作,那么就無法回滾了,數(shù)據(jù)可能會(huì)出錯(cuò)。

總結(jié)

觸發(fā)器是基于行觸發(fā)的,所以刪除、新增或者修改操作可能都會(huì)激活觸發(fā)器,所以不要編寫過于復(fù)雜的觸發(fā)器,也不要增加過得的觸發(fā)器,這樣會(huì)對(duì)數(shù)據(jù)的插入、修改或者刪除帶來比較嚴(yán)重的影響,同時(shí)也會(huì)帶來可移植性差的后果,所以在設(shè)計(jì)觸發(fā)器的時(shí)候一定要有所考慮。

觸發(fā)器是一種特殊的存儲(chǔ)過程,它在插入,刪除或修改特定表中的數(shù)據(jù)時(shí)觸發(fā)執(zhí)行,它比數(shù)據(jù)庫本身標(biāo)準(zhǔn)的功能有更精細(xì)和更復(fù)雜的數(shù)據(jù)控制能力。

數(shù)據(jù)庫觸發(fā)器有以下的作用:

1.安全性??梢曰跀?shù)據(jù)庫的值使用戶具有操作數(shù)據(jù)庫的某種權(quán)利。

  # 可以基于時(shí)間限制用戶的操作,例如不允許下班后和節(jié)假日修改數(shù)據(jù)庫數(shù)據(jù)。

  # 可以基于數(shù)據(jù)庫中的數(shù)據(jù)限制用戶的操作,例如不允許股票的價(jià)格的升幅一次超過10%。

2.審計(jì)??梢愿櫽脩魧?duì)數(shù)據(jù)庫的操作。   

  # 審計(jì)用戶操作數(shù)據(jù)庫的語句。

  # 把用戶對(duì)數(shù)據(jù)庫的更新寫入審計(jì)表。

3.實(shí)現(xiàn)復(fù)雜的數(shù)據(jù)完整性規(guī)則

  # 實(shí)現(xiàn)非標(biāo)準(zhǔn)的數(shù)據(jù)完整性檢查和約束。觸發(fā)器可產(chǎn)生比規(guī)則更為復(fù)雜的限制。與規(guī)則不同,觸發(fā)器可以引用列或數(shù)據(jù)庫對(duì)象。例如,觸發(fā)器可回退任何企圖吃進(jìn)超過自己保證金的期貨。

  # 提供可變的缺省值。

4.實(shí)現(xiàn)復(fù)雜的非標(biāo)準(zhǔn)的數(shù)據(jù)庫相關(guān)完整性規(guī)則。觸發(fā)器可以對(duì)數(shù)據(jù)庫中相關(guān)的表進(jìn)行連環(huán)更新。例如,在auths表author_code列上的刪除觸發(fā)器可導(dǎo)致相應(yīng)刪除在其它表中的與之匹配的行。

  # 在修改或刪除時(shí)級(jí)聯(lián)修改或刪除其它表中的與之匹配的行。

  # 在修改或刪除時(shí)把其它表中的與之匹配的行設(shè)成NULL值。

  # 在修改或刪除時(shí)把其它表中的與之匹配的行級(jí)聯(lián)設(shè)成缺省值。

  # 觸發(fā)器能夠拒絕或回退那些破壞相關(guān)完整性的變化,取消試圖進(jìn)行數(shù)據(jù)更新的事務(wù)。當(dāng)插入一個(gè)與其主健不匹配的外部鍵時(shí),這種觸發(fā)器會(huì)起作用。例如,可以在books.author_code 列上生成一個(gè)插入觸發(fā)器,如果新值與auths.author_code列中的某值不匹配時(shí),插入被回退。

5.同步實(shí)時(shí)地復(fù)制表中的數(shù)據(jù)。

6.自動(dòng)計(jì)算數(shù)據(jù)值,如果數(shù)據(jù)的值達(dá)到了一定的要求,則進(jìn)行特定的處理。例如,如果公司的帳號(hào)上的資金低于5萬元?jiǎng)t立即給財(cái)務(wù)人員發(fā)送警告數(shù)據(jù)。

到此這篇關(guān)于mysql觸發(fā)器trigger實(shí)例詳解的文章就介紹到這了,更多相關(guān)mysql觸發(fā)器實(shí)例內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • VS2013連接MySQL5.6成功案例一枚

    VS2013連接MySQL5.6成功案例一枚

    這篇文章主要為大家分享了VS2013連接MySQL5.6成功案例一枚,很有實(shí)用性,感興趣的小伙伴們可以參考一下
    2016-05-05
  • MySQL生產(chǎn)環(huán)境CPU使用率過高的排查與解決方案

    MySQL生產(chǎn)環(huán)境CPU使用率過高的排查與解決方案

    在生產(chǎn)環(huán)境中,MySQL作為一個(gè)關(guān)鍵的數(shù)據(jù)庫組件,其性能對(duì)整個(gè)系統(tǒng)的穩(wěn)定性至關(guān)重要,有時(shí)候我們可能會(huì)遇到MySQL CPU使用率過高的問題,本文將詳細(xì)介紹如何排查和解決MySQL CPU過高的問題,幫助您迅速恢復(fù)正常的數(shù)據(jù)庫性能,需要的朋友可以參考下
    2024-03-03
  • 將SQL查詢結(jié)果保存為新表的方法實(shí)例

    將SQL查詢結(jié)果保存為新表的方法實(shí)例

    有時(shí)我們要把查詢的結(jié)果保存到新表里,創(chuàng)建新表,查詢,插入顯得十分麻煩,下面這篇文章主要給大家介紹了關(guān)于將SQL查詢結(jié)果保存為新表的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 有效查詢MySQL表中重復(fù)數(shù)據(jù)的方法和技巧分享

    有效查詢MySQL表中重復(fù)數(shù)據(jù)的方法和技巧分享

    在MySQL數(shù)據(jù)庫中,偶爾會(huì)遇到需要查找表中出現(xiàn)的重復(fù)數(shù)據(jù)的情況,這種情況下,我們可以通過編寫一些SQL查詢語句輕松地找到并處理這些重復(fù)行,本文將介紹一些常見的方法和技巧,幫助你有效地查詢MySQL表中的重復(fù)數(shù)據(jù),需要的朋友可以參考下
    2023-10-10
  • Win10下mysql 8.0.15 安裝配置方法圖文教程

    Win10下mysql 8.0.15 安裝配置方法圖文教程

    這篇文章主要為大家詳細(xì)介紹了Win10下mysql 8.0.15 安裝配置方法圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • MySQL之索引結(jié)構(gòu)解讀

    MySQL之索引結(jié)構(gòu)解讀

    這篇文章主要介紹了MySQL之索引結(jié)構(gòu)解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • MySQL如何運(yùn)行sql文件圖文詳解(以Navicat做演示)

    MySQL如何運(yùn)行sql文件圖文詳解(以Navicat做演示)

    Navicat是MySQL非常好用的可視化管理工具,功能非常強(qiáng)大,能滿足我們?nèi)粘?shù)據(jù)庫開發(fā)的所有需求,這篇文章主要給大家介紹了關(guān)于MySQL如何運(yùn)行sql文件(以Navicat做演示)的相關(guān)資料,需要的朋友可以參考下
    2024-08-08
  • 使用pt-kill根據(jù)一定的規(guī)則來kill連接的方法

    使用pt-kill根據(jù)一定的規(guī)則來kill連接的方法

    pt-kill 是一個(gè)優(yōu)秀的kill MySQL連接的一個(gè)工具,是percona toolkit的一部分,在因?yàn)榭臻e連接較多導(dǎo)致超過最大連接數(shù)、某個(gè)有問題的sql導(dǎo)致mysql負(fù)載很高時(shí),都需要將一些連接kill掉,這個(gè)工具主要就是這個(gè)用途
    2016-04-04
  • MySQL從命令行導(dǎo)入SQL腳本時(shí)出現(xiàn)中文亂碼的解決方法

    MySQL從命令行導(dǎo)入SQL腳本時(shí)出現(xiàn)中文亂碼的解決方法

    這篇文章主要介紹了MySQL從命令行導(dǎo)入SQL腳本時(shí)出現(xiàn)中文亂碼的解決方法,分析了中文亂碼出現(xiàn)的原因并給出了兩種解決方法供大家參考,需要的朋友可以參考下
    2016-09-09
  • MySQL學(xué)習(xí)筆記之?dāng)?shù)據(jù)的增、刪、改實(shí)現(xiàn)方法

    MySQL學(xué)習(xí)筆記之?dāng)?shù)據(jù)的增、刪、改實(shí)現(xiàn)方法

    這篇文章主要介紹了MySQL學(xué)習(xí)筆記之?dāng)?shù)據(jù)的增、刪、改實(shí)現(xiàn)方法,簡(jiǎn)單介紹了mysql實(shí)現(xiàn)數(shù)據(jù)的增、刪、改相關(guān)語法與使用技巧,需要的朋友可以參考下
    2016-09-09

最新評(píng)論