日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

MySQL 觸發器的使用及需要注意的地方

瀏覽:20日期:2023-10-06 14:07:47
關于觸發器

現實開發中我們經常會遇到這種情況,比如添加、刪除和修改信息的時候需要記錄日志,我們就要在完成常規的數據庫邏輯操作之后再去寫入日志表,這樣變成了兩步操作,更復雜了。

又比如刪除一個人員信息的時候,需要將他的購物記錄、收貨地址、收藏夾等都刪了,這個連續的操作容易出錯,一致性和完整性不好保證。這時候就要使用觸發器,既可以免去一堆的業務邏輯代碼,又能更好的保證數據完整性。

觸發器(trigger)是一種與表有關的數據庫對象:在滿足定義條件時觸發某種操作,并執行觸發器中定義的語句集合。觸發器的這種特性可以協助應用在數據庫端保證數據的完整性。

它是一種與表事件相關的特殊的存儲過程,當對一個表進行操作( insert,delete, update)時就會激活執行。

觸發器的使用創建觸發器

創建觸發器的語法如下:

CREATE TRIGGER trigger_name trigger_time trigger_event ON t_name FOR EACH ROW trigger_stmt

說明:

trigger_name:觸發器名稱

tirgger_time:觸發執行時間點,數據操作前(BEFORE) 或者 數據操作后(AFTER)

trigger_event:觸發事件,增(INSERT)、刪(DELETE)、改(UPDATE)

t_name:指的是在 t_name 這張表上建立觸發器

trigger_stmt:觸發器的程序體,可以是一條SQL語句或者是用BEGIN和END包含的多條語句

觸發器只能創建在永久表(Permanent)上,不能創建在臨時表(Temporary)上

FOR EACH ROW 固定表達式,表示任何一條記錄上的操作滿足觸發事件都會觸發該觸發器

tirgger_time有兩種類型,trigger_event有三種類型,所以他們一共有6種組合:BEFORE INSERT,BEFORE DELETE,BEFORE UPDATE,AFTER INSERT,AFTER DELETE,AFTER UPDATE

示例(先創建一個日志表,用于觸發器觸發時候填入值):

/*先創建一個日志表,用于觸發器觸發時候填入值*/mysql> DROP TABLE IF EXISTS `TriggerLog`;Query OK, 0 rows affectedmysql> CREATE TABLE `TriggerLog`( `id` INT auto_increment PRIMARY KEY, `trigger_time` VARCHAR(30), `trigger_event` VARCHAR(30), `memo` VARCHAR(200));Query OK, 0 rows affected

Insert類型觸發器:

mysql>/*這邊聲明SQL腳本的結束符為// */DELIMITER //DROP TRIGGER IF EXISTS trig_after_insert;CREATE TRIGGER trig_after_insert AFTER INSERT ON students FOR EACH ROWBEGIN insert into `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) values (’after’,’insert’,concat(’new student info,id:’,cast(new.studentid as char)));END //Query OK, 0 rows affectedmysql>/*重置SQL腳本的結束符為; */DELIMITER ;Query OK, 0 rows affectedmysql>/*插入一條數據 */insert into students(studentname,score,classid) values(’trigger1’,100,0);Query OK, 1 row affectedmysql>/*查詢日志表看是否有觸發寫入 */select * from `TriggerLog`;+----+--------------+---------------+------------------------+| id | trigger_time | trigger_event | memo |+----+--------------+---------------+------------------------+| 1 | after | insert | new student info,id:21 |+----+--------------+---------------+------------------------+1 row in set

Update類型觸發器:

mysql>/*這邊聲明SQL腳本的結束符為// */DELIMITER //DROP TRIGGER IF EXISTS trig_after_update;CREATE TRIGGER trig_after_update AFTER UPDATE ON students FOR EACH ROWBEGIN insert into `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) values (’after’,’update’,concat(’update student info,id:’,cast(new.studentid as char)));END //Query OK, 0 rows affectedmysql>/*重置SQL腳本的結束符為; */DELIMITER ;Query OK, 0 rows affectedmysql>/*更新數據 */update students set score=99 where studentname=’trigger1’;Query OK, 1 row affectedRows matched: 1 Changed: 1 Warnings: 0mysql>/*查詢日志表看是否更新的時候有觸發寫入 */select * from `TriggerLog`;+----+--------------+---------------+---------------------------+| id | trigger_time | trigger_event | memo |+----+--------------+---------------+---------------------------+| 1 | after | insert | new student info,id:21 || 2 | after | update | update student info,id:21 |+----+--------------+---------------+---------------------------+2 rows in set

Delete類型觸發器:

mysql>/*這邊聲明SQL腳本的結束符為// */DELIMITER //DROP TRIGGER IF EXISTS trig_after_delete;CREATE TRIGGER trig_after_delete AFTER DELETE ON students FOR EACH ROWBEGIN insert into `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) values (’after’,’update’,concat(’delete student info,id:’,cast(old.studentid as char)));END //Query OK, 0 rows affectedmysql>/*重置SQL腳本的結束符為; */DELIMITER ;Query OK, 0 rows affectedmysql>/* 刪除數據 */delete from students where studentid=21;Query OK, 1 row affectedmysql>/*查詢日志看刪除是否有觸發寫入*/select * from `TriggerLog`;+----+--------------+---------------+---------------------------+| id | trigger_time | trigger_event | memo |+----+--------------+---------------+---------------------------+| 1 | after | insert | new student info,id:21 || 2 | after | update | update student info,id:21 || 3 | after | update | delete student info,id:21 |+----+--------------+---------------+---------------------------+3 rows in set查看觸發器

查看全部觸發器

show triggers; --語法

mysql> show triggers;+-------------------+--------+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+--------------------------------------------+----------------+----------------------+----------------------+--------------------+| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |+-------------------+--------+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+--------------------------------------------+----------------+----------------------+----------------------+--------------------+| trig_after_insert | INSERT | students | BEGIN insert into `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) values (’after’,’insert’,concat(’new student info,id:’,cast(new.studentid as char)));END | AFTER | NULL | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | root@localhost | utf8 | utf8_general_ci | latin1_swedish_ci || trig_after_update | UPDATE | students | BEGIN insert into `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) values (’after’,’update’,concat(’update student info,id:’,cast(new.studentid as char)));END | AFTER | NULL | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | root@localhost | utf8 | utf8_general_ci | latin1_swedish_ci || trig_after_delete | DELETE | students | BEGIN insert into `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) values (’after’,’update’,concat(’delete student info,id:’,cast(old.studentid as char)));END | AFTER | NULL | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | root@localhost | utf8 | utf8_general_ci | latin1_swedish_ci |+-------------------+--------+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+--------------------------------------------+----------------+----------------------+----------------------+--------------------+3 rows in set

查看觸發器的創建語句

show create trigger trigger_name; --語法

mysql> show create trigger trig_after_insert;+-------------------+--------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+| Trigger | sql_mode | SQL Original Statement | character_set_client | collation_connection | Database Collation |+-------------------+--------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+| trig_after_insert | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`localhost` TRIGGER trig_after_insert AFTER INSERT ON students FOR EACH ROWBEGIN insert into `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) values (’after’,’insert’,concat(’new student info,id:’,cast(new.studentid as char)));END | utf8 | utf8_general_ci | latin1_swedish_ci |+-------------------+--------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+1 row in set刪除觸發器

drop trigger trigger_name; --語法

mysql> drop trigger trig_after_insert;Query OK, 0 rows affected mysql> show create trigger trig_after_insert;1360 - Trigger does not exist 使用時的注意點NEW / OLD的使用區別

觸發器針對的是數據庫中的每一行記錄,每行數據在操作前后都會有一個對應的狀態,觸發器將沒有操作之前的狀態保存到 old 關鍵字中,將操作后的狀態保存到 new 中

new.cname --新增行(或修改前的行)的某列數據 old.cname --刪除行(或修改后的行)的某列數據

需要注意的是,old 和 new 不是所有觸發器都有

觸發器類型 new和old的使用 INSERT型觸發器 沒有 old,只有 new,new 表示將要(插入前)或者已經增加(插入后)的數據 UPDATE型觸發器 既有 old 也有 new,old 表示更新之前的數據,new 表示更新之后的數據 DELETE型觸發器 沒有 new,只有 old,old 表示將要(刪除前)或者已經被刪除(刪除后)的數據

其實我們上面已經用過 new/old 來創建觸發器并獲取數據,我們根據這個表格重新來修改下那個更新觸發器(trig_after_update),輸出修改前和修改后的內容比較:

mysql>/*這邊聲明SQL腳本的結束符為// */DELIMITER //DROP TRIGGER IF EXISTS trig_after_update;CREATE TRIGGER trig_after_update AFTER UPDATE ON students FOR EACH ROWBEGIN insert into `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) values (’after’,’update’,concat(’from:’,old.studentname,’,’,old.score,’ ’,’to:’,new.studentname,’,’,new.score));END //Query OK, 0 rows affectedmysql>/*重置SQL腳本的結束符為; */DELIMITER ;Query OK, 0 rows affectedmysql>/*更新成績和名稱 */update students set score=106,studentname=’trigger2’ where studentid=17;Query OK, 1 row affectedRows matched: 1 Changed: 1 Warnings: 0mysql>/*根據old和new 對比更新前后的值 */select * from `TriggerLog`;+----+--------------+---------------+--------------------------------------+| id | trigger_time | trigger_event | memo |+----+--------------+---------------+--------------------------------------+| 1 | after | insert | new student info,id:21|| 2 | after | update | update student info,id:21 || 3 | after | update | delete student info,id:21 || 4 | after | update | from:test2,101.00 to:trigger2,106.00 |+----+--------------+---------------+--------------------------------------+4 rows in set無法觸發對同表的修改

MySQL 的觸發器中不能對本表進行 insert、update 和 delete 操作,否則會報錯

mysql>/*這邊聲明SQL腳本的結束符為// */DELIMITER //DROP TRIGGER IF EXISTS trig_after_insert;CREATE TRIGGER trig_after_insert AFTER INSERT ON students FOR EACH ROWBEGIN update students set score = score+1 where studentid= new.studentid;END //Query OK, 0 rows affectedmysql>/*重置SQL腳本的結束符為; */DELIMITER ;Query OK, 0 rows affectedmysql>/*插入一條數據之后因為觸發了對本表的修改,所以報錯了 */insert into students(studentname,score,classid) values(’trigger2’,101,0);1442 - Can’t update table ’students’ in stored function/trigger because it is already used by statement which invoked this stored function/trigger.小結

1、觸發器可以通過數據庫中的關聯表實現級聯更改,即一張表數據的改變會影響其他表的數據,如數據修改,數據統計,數據復制等。2、可以保證數據安全,并進行安全校驗,限制用戶具有操作數據庫的某種權利。3、可以對復雜邏輯的實現進行數據完整性檢查和約束。4、使用觸發器的要應需而用,如果過分依賴觸發器,會影響數據庫的結構,增加數據庫的執行和維護成本。5、觸發器有BEFORE觸發器和AFTER觸發器的卻別,所以它的執行步驟是先執行 BEFORE觸發器,再執行業務腳本,最后執行AFTER觸發器。需要注意的是 某一個步驟錯誤后就不再執行了, 如果是事務表,會被回滾,如果是非事務表,那么就無法回滾了,數據可能有不一致性。

觸發器的兩種限制

1、觸發程序不能調用將數據返回客戶端的存儲程序,也不能使用采用CALL語句的動態SQL語句,但是允許存儲程序通過參數將數據返回觸發程序,也就是存儲過程或者函數通過OUT或者INOUT類型的參數將數據返回觸發器是可以的,但是不能調用直接返回數據的過程。2、不能再觸發器中使用以顯示或隱式方式開始或結束事務的語句,如START TRANS-ACTION,COMMIT或ROLLBACK。

以上就是MySQL 觸發器的使用及需要注意的地方的詳細內容,更多關于MySQL 觸發器的資料請關注好吧啦網其它相關文章!

標簽: MySQL 數據庫
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久精品高清| 五月天久久网站| 日日夜夜免费精品| 免费视频最近日韩| 午夜久久99| 日韩精品一二区| 中文字幕av亚洲精品一部二部| 伊人影院久久| 免费成人在线观看| 奶水喷射视频一区| 亚洲精品黄色| 欧美亚洲自偷自偷| 国产精品v亚洲精品v日韩精品| 美女视频黄 久久| 国产色播av在线| 亚洲成人二区| 久久国产精品亚洲77777| 亚洲v天堂v手机在线| 国产欧美一区二区三区精品观看| 欧美日韩伊人| 精品不卡一区| 韩日一区二区三区| 热久久久久久久| 日韩精品五月天| 国产精品99精品一区二区三区∴| 国产一区2区在线观看| 91精品一区国产高清在线gif| 日韩亚洲精品在线| 91亚洲精品在看在线观看高清| 国产欧美日韩一区二区三区四区| 精品国产黄a∨片高清在线| 国产在线|日韩| 热久久国产精品| 久久精品资源| 久久久五月天| 日本中文字幕一区二区| 精品免费视频| 国产视频亚洲| 欧美精品97| 亚洲精品99| 国产精品大片| 欧美日韩第一| 国产精品免费99久久久| 99精品视频精品精品视频| 亚洲欧美在线综合| 91一区二区| 亚洲欧美日本国产| 国产91在线播放精品| 亚洲深夜av| 另类综合日韩欧美亚洲| 欧美 日韩 国产一区二区在线视频 | 日韩av免费大片| 亚洲国内欧美| 国产日韩亚洲欧美精品| 久久精品国产亚洲夜色av网站| 婷婷视频一区二区三区| 国产精品成久久久久| 丝袜美腿一区二区三区| 成人在线丰满少妇av| 免费视频一区二区| 亚洲国产福利| 欧美一区不卡| 伊人精品在线| 成人一区而且| 国产午夜一区| 亚洲综合精品四区| 色欧美自拍视频| 日韩视频1区| 黄色欧美日韩| 国产91欧美| 欧美一区成人| 久久精品国内一区二区三区水蜜桃| 国产一卡不卡| 国产亚洲精品v| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 狠狠操综合网| 成人亚洲精品| 欧美日韩国产一区二区在线观看| 国产一区二区中文| 精品免费视频| 国产欧美日韩在线一区二区| 99在线|亚洲一区二区| 日本久久黄色| 国产精品白浆| 亚洲免费观看高清完整版在线观| 亚洲a一区二区三区| 精品国产欧美| 国产精品久久久免费| 亚洲最大av| 亚洲一区久久| 婷婷亚洲五月色综合| 欧洲一区二区三区精品| 麻豆精品视频在线观看视频| 亚洲va久久久噜噜噜久久| 日韩视频二区| 激情五月综合网| 99久精品视频在线观看视频| 高清av不卡| 97精品国产| 国产精品成人**免费视频| 日韩一区中文| 亚洲伊人精品酒店| 亚洲精品中文字幕乱码| 在线一区av| 国产一区二区三区黄网站| 国产麻豆一区| 欧美日韩一区二区国产| 日韩成人精品一区二区三区 | 国产综合婷婷| 日韩欧美一区二区三区在线观看| 国产精久久久| 国产精品一区免费在线| 国产探花一区在线观看| 日韩精品久久理论片| 日本大胆欧美人术艺术动态| 午夜一级久久| 亚洲经典在线| 久久www成人_看片免费不卡| 亚洲一区二区三区免费在线观看 | 女人天堂亚洲aⅴ在线观看| 国产91一区| 欧美日韩在线网站| 久久久久99| 亚洲女同中文字幕| 99亚洲精品| 日韩中文字幕麻豆| 综合精品一区| 欧美一区影院| 久久gogo国模啪啪裸体| 久久尤物视频| 热三久草你在线| 国产精品亚洲一区二区三区在线观看| av免费不卡国产观看| 欧美羞羞视频| 国产国产精品| av成人国产| 久久亚洲视频| 日韩欧美激情电影| 国产精品蜜月aⅴ在线| 国产成人精品一区二区三区在线| 天堂а√在线最新版中文在线| 99热精品久久| 三级一区在线视频先锋| 日韩av一级片| 麻豆高清免费国产一区| 国产伦久视频在线观看| 免费国产自久久久久三四区久久| 亚洲一区二区成人| 97久久亚洲| 国产中文欧美日韩在线| 性欧美xxxx免费岛国不卡电影| 久久久久欧美精品| 亚洲欧美日韩国产综合精品二区| 日本成人手机在线| 精品亚洲成人| 99精品网站| 亚洲天堂av资源在线观看| 国产精品久久777777毛茸茸| 午夜av不卡| 免费成人av在线播放| 国产精品99久久免费| 久久视频一区| 中文字幕视频精品一区二区三区 | 日韩视频网站在线观看| 亚洲福利国产| 热久久国产精品| 免费在线日韩av| 欧美日韩一二| 日韩高清在线不卡| 国产66精品| 蘑菇福利视频一区播放| 国产精品九九| 激情久久中文字幕| 日产欧产美韩系列久久99| 精品欠久久久中文字幕加勒比| 欧美日韩激情在线一区二区三区| 天堂俺去俺来也www久久婷婷| 免费在线欧美黄色| 在线成人动漫av| 国产日韩1区| 日韩精品中文字幕第1页| 久久xxxx精品视频| 成人国产精品| 亚洲三级观看| 国产精品久久久久蜜臀| 樱桃成人精品视频在线播放| 国产美女亚洲精品7777| 蜜桃一区二区三区| 久久天堂成人| 伊人精品一区| 日韩综合在线| 国产精品jk白丝蜜臀av小说| 亚洲人成网77777色在线播放 | 亚洲精品电影| 国产精品99视频| 国产剧情一区| 亚洲日本三级| 天堂成人国产精品一区| 激情综合自拍| 久久精品123|