一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術(shù)及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫技術(shù)|

服務器之家 - 數(shù)據(jù)庫 - Mysql - 詳解mysql觸發(fā)器trigger實例

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

2022-02-16 18:52周伯通的麥田 Mysql

這篇文章主要為大家介紹了mysql觸發(fā)器trigger實例 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

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

什么是觸發(fā)器

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

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

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

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

?
1
2
3
4
5
6
7
8
9
create trigger trigger_name trigger_time trigger_event on tb_name for each row trigger_stmt
trigger_name:觸發(fā)器的名稱
tirgger_time:觸發(fā)時機,為before或者after
trigger_event:觸發(fā)事件,為insertdelete或者update
tb_name:表示建立觸發(fā)器的表明,就是在哪張表上建立觸發(fā)器
trigger_stmt:觸發(fā)器的程序體,可以是一條sql語句或者是用beginend包含的多條語句
所以可以說mysql創(chuàng)建以下六種觸發(fā)器:
before insert,before delete,before update
after insert,after delete,after update

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

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

for each row表示任何一條記錄上的操作滿足觸發(fā)事件都會觸發(fā)該觸發(fā)器

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

?
1
2
3
4
5
create trigger 觸發(fā)器名 before|after 觸發(fā)事件
on 表名 for each row
begin
    執(zhí)行語句列表
end

其中,begin與end之間的執(zhí)行語句列表參數(shù)表示需要執(zhí)行的多個語句,不同語句用分號隔開

tips:

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
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é)束符號定義為||,中間定義一個觸發(fā)器,一旦有滿足條件的刪除操作

就會執(zhí)行begin和end中的語句,接著使用||結(jié)束

最后使用delimiter ; 將結(jié)束符號還原

tigger_event:

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

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

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

?
1
2
3
4
5
6
7
8
delimiter $  #將語句的分隔符改為$
begin
sql1;
sql2;
...
sqln
end $
delimiter ;  #將語句的分隔符改回原來的分號";"

在begin...end語句中也可以定義變量,但是只能在begin...end內(nèi)部使用:

?
1
2
declare var_name var_type [default value] #定義變量,可指定默認值
set var_name = value  #給變量賦值

new和old的使用:

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

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

?
1
2
new.columnname:新增行的某列數(shù)據(jù)
old.columnname:刪除行的某列數(shù)據(jù)

說了這么多現(xiàn)在我們來創(chuàng)建一個觸發(fā)器吧!

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

用戶users表

?
1
2
3
4
5
6
7
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表:

?
1
2
3
4
5
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='日志表';

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

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

?
1
2
3
4
5
6
7
8
9
10
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)亂碼,這里設置字符集
set s2 = " is created";
set s1 = concat(new.name,s2);     #函數(shù)concat可以將字符串連接
insert into logs(log) values(s1);
end $
delimiter ;

這里我用的navicat:

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

查看觸發(fā)器

show triggers語句查看觸發(fā)器信息

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

tip:

?
1
上面我用的navicat直接創(chuàng)建,如果大家用的mysql front,name這里會有個區(qū)別,我們刪除剛才的觸發(fā)器,在mysql front中測試
?
1
drop trigger  user_log;#刪除觸發(fā)器

打開mysql front:

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

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

?
1
2
3
4
5
6
7
8
9
10
#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 ;

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

這里再啰嗦幾句:

tipsshow triggers語句無法查詢指定的觸發(fā)器

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

?
1
select * from information_schema.triggers;

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

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

?
1
select * from information_schema.triggers where trigger_name='user_log';

tips:

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

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

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

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

好吧,我們再來查看一下logs表吧!

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

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

限制和注意事項

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

1.觸發(fā)程序不能調(diào)用將數(shù)據(jù)返回客戶端的存儲程序,也不能使用采用call語句的動態(tài)sql語句,但是允許存儲程序通過參數(shù)將數(shù)據(jù)返回觸發(fā)程序,也就是存儲過程或者函數(shù)通過out或者inout類型的參數(shù)將數(shù)據(jù)返回觸發(fā)器是可以的,但是不能調(diào)用直接返回數(shù)據(jù)的過程。

2.不能再觸發(fā)器中使用以顯示或隱式方式開始或結(jié)束事務的語句,如start trans-action,commit或rollback。

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

總結(jié)

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

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

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

1.安全性。可以基于數(shù)據(jù)庫的值使用戶具有操作數(shù)據(jù)庫的某種權(quán)利。

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

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

2.審計。可以跟蹤用戶對數(shù)據(jù)庫的操作。

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

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

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

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

# 提供可變的缺省值。

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

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

# 在修改或刪除時把其它表中的與之匹配的行設成null值。

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

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

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

6.自動計算數(shù)據(jù)值,如果數(shù)據(jù)的值達到了一定的要求,則進行特定的處理。例如,如果公司的帳號上的資金低于5萬元則立即給財務人員發(fā)送警告數(shù)據(jù)。

無論從事什么行業(yè),只要做好兩件事就夠了,一個是你的專業(yè)、一個是你的人品,專業(yè)決定了你的存在,人品決定了你的人脈,剩下的就是堅持,用善良專業(yè)和真誠贏取更多的信任。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內(nèi)容!

原文鏈接:https://www.cnblogs.com/phpper/p/7587031.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 天天舔天天干 | 美女脱了内裤让男生尿囗 | 热国产热综合 | 亚洲无限观看 | 美女和男人免费网站视频 | 高清在线观看免费 | 久久综合狠狠综合狠狠 | 91色香sxmv最网页版新地址 | 99视频全部看免费观 | 911精品国产亚洲日本美国韩国 | 日本黄色大片免费观看 | 情人我吃糖果小说 | h视频免费高清在线观看 | 菠萝视频污 | 国产精品久久久久这里只有精品 | 日本96在线精品视频免费观看 | 王淑兰李思雨李铁柱乡村小说免费 | 啊啊啊好大在线观看 | caopren免费视频国产 | 日韩一级欧美一级一级国产 | 四川一级毛片 | 美女翘臀跪床被打屁股作文 | 日韩成人免费 | 免费欧美视频 | 精品久久一区 | 亚洲午夜性春猛交xxxx | 久久国产加勒比精品无码 | 99久久精品免费看国产一区二区 | 99久久精品久久久久久清纯 | 成人私人影院www片免费高清 | 催眠白丝舞蹈老师小说 | 色视频综合| 成人永久免费福利视频网站 | 无套内射在线观看THEPORN | 奇米影视7777久久精品 | 96av视频在线观看 | 色天天色综合 | free性丰满hd性欧美人体 | 亚洲狼人综合干 | 帅小伙和警官同性3p | 99久久综合给久久精品 |