最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

什么是觸發(fā)器

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

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

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

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

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語(yǔ)句或者是用BEGIN和END包含的多條語(yǔ)句
所以可以說(shuō)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í)行語(yǔ)句的觸發(fā)器

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

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

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

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

     當(dāng)觸發(fā)器創(chuàng)建完成后,可以用DELIMITER ;來(lái)將結(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 ;

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

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

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

tigger_event:

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

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

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

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

NEW.columnname:新增行的某列數(shù)據(jù)
OLD.columnname:刪除行的某列數(shù)據(jù)
說(shuō)了這么多現(xiàn)在我們來(lái)創(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 '日志說(shuō)明',
 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語(yǔ)句查看觸發(fā)器信息

Tip:

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

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

打開(kāi)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語(yǔ)句無(wú)法查詢指定的觸發(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ù)庫(kù)下的triggers表中

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

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

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

好吧,我們?cè)賮?lái)查看一下logs表吧!

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

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

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

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

2.不能再觸發(fā)器中使用以顯示或隱式方式開(kāi)始或結(jié)束事務(wù)的語(yǔ)句,如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)行操作,那么就無(wú)法回滾了,數(shù)據(jù)可能會(huì)出錯(cuò)。

總結(jié)

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

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

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

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

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

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

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

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

  # 把用戶對(duì)數(shù)據(jù)庫(kù)的更新寫(xiě)入審計(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ù)庫(kù)對(duì)象。例如,觸發(fā)器可回退任何企圖吃進(jìn)超過(guò)自己保證金的期貨。

  # 提供可變的缺省值。

4.實(shí)現(xiàn)復(fù)雜的非標(biāo)準(zhǔn)的數(shù)據(jù)庫(kù)相關(guān)完整性規(guī)則。觸發(fā)器可以對(duì)數(shù)據(jù)庫(kù)中相關(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萬(wàn)元?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)文章

  • MySQL中union和union all區(qū)別

    MySQL中union和union all區(qū)別

    今天和大家聊一聊,面試中可能遇到的一個(gè)知識(shí)點(diǎn),就是union與union all的區(qū)別,具有一定的參考價(jià)值,對(duì)面試和知識(shí)總結(jié)有一定的幫助,感興趣的可以了解一下
    2023-08-08
  • IDEA連接mysql又報(bào)錯(cuò)!Server returns invalid timezone. Go to tab and set serverTimezone  prope的問(wèn)題

    IDEA連接mysql又報(bào)錯(cuò)!Server returns invalid timezone. Go to tab an

    這篇文章主要介紹了IDEA連接mysql又報(bào)錯(cuò)!Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' prope問(wèn)題,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2020-05-05
  • Mysql的數(shù)據(jù)庫(kù)遷移到另一個(gè)機(jī)器上的方法詳解

    Mysql的數(shù)據(jù)庫(kù)遷移到另一個(gè)機(jī)器上的方法詳解

    今天小編就為大家分享一篇關(guān)于Mysql的數(shù)據(jù)庫(kù)遷移到另一個(gè)機(jī)器上的方法詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • mysql(master/slave)主從復(fù)制原理及配置圖文詳解

    mysql(master/slave)主從復(fù)制原理及配置圖文詳解

    這篇文章主要介紹了mysql(master/slave)主從復(fù)制原理及配置圖文詳解,以前腳本之家小編發(fā)過(guò)相關(guān)的內(nèi)容,但這么好的非常少見(jiàn)特分享一下,需要的朋友可以參考下
    2016-05-05
  • mysql語(yǔ)句如何插入含單引號(hào)或反斜杠的值詳解

    mysql語(yǔ)句如何插入含單引號(hào)或反斜杠的值詳解

    這篇文章主要給大家介紹了關(guān)于mysql語(yǔ)句如何插入含單引號(hào)或反斜杠的值的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • MySQL存儲(chǔ)函數(shù)以及觸發(fā)器詳解

    MySQL存儲(chǔ)函數(shù)以及觸發(fā)器詳解

    這篇文章詳細(xì)給大家介紹了MySQL-SQL存儲(chǔ)函數(shù)以及觸發(fā)器,文中有詳細(xì)的代碼示例,對(duì)我們學(xué)習(xí)MySQL有一定的幫助,感興趣的朋友可以參考閱讀下
    2023-06-06
  • 深入淺析MySQL從刪庫(kù)到跑路_高級(jí)(一)——數(shù)據(jù)完整性

    深入淺析MySQL從刪庫(kù)到跑路_高級(jí)(一)——數(shù)據(jù)完整性

    數(shù)據(jù)完整性是指數(shù)據(jù)的可靠性和準(zhǔn)確性,數(shù)據(jù)完整性類型有四種,本文給大家提到,接下來(lái)通過(guò)本文給大家介紹MySQL從刪庫(kù)到跑路的內(nèi)容分析,感興趣的朋友跟隨小編一起看看吧
    2018-11-11
  • 關(guān)于MySQL報(bào)警的一次分析處理詳解

    關(guān)于MySQL報(bào)警的一次分析處理詳解

    這篇文章主要給大家介紹了關(guān)于MySQL報(bào)警的一次分析處理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Mysql保持現(xiàn)有內(nèi)容在后面增加內(nèi)容的sql語(yǔ)句

    Mysql保持現(xiàn)有內(nèi)容在后面增加內(nèi)容的sql語(yǔ)句

    這篇文章主要介紹了Mysql保持現(xiàn)有內(nèi)容在后面增加內(nèi)容的sql語(yǔ)句,需要的朋友可以參考下
    2017-05-05
  • MySQL中觸發(fā)器和游標(biāo)的介紹與使用

    MySQL中觸發(fā)器和游標(biāo)的介紹與使用

    這篇文章主要給大家介紹了關(guān)于MySQL中觸發(fā)器和游標(biāo)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評(píng)論

岗巴县| 灌云县| 广宗县| 岑溪市| 西青区| 乐陵市| 县级市| 长泰县| 紫阳县| 临城县| 聊城市| 芜湖市| 忻城县| 正安县| 高要市| 工布江达县| 通山县| 龙岩市| 莲花县| 无极县| 铁岭县| 宁武县| 甘孜| 浪卡子县| 河西区| 嵩明县| 临泉县| 吉木乃县| 平罗县| 吴川市| 长丰县| 通化县| 英超| 理塘县| 武乡县| 麟游县| 双辽市| 禄丰县| 曲阳县| 微山县| 普洱|