文章目錄
觸發器的基本概念
觸發器是和表相關聯的一個數據庫對象,是一種特殊的存儲過程。
例如:某個表發生一個事件(增刪改操作),然後自動的執行預先編譯好的 SQL 語句,執行相關操作。
這樣保證了數據的完整性。
觸發器關鍵字: trigger
基本作用:通過對錶進行數據的插入、更新或刪除等操作來觸發,就會執行特定的存儲過程
觸發器的創建
可以字MySQL命令界面 ? create trigger 命令查看創建觸發器的格式。
create trigger trigger_name #[觸發器名]
觸發時機 #觸發時機:before|after
觸發條件 #觸發條件:insert|update|delete
on tbl_name #表名
for each row #對每一行
trigger_body #執行的操作
總的來說就是對錶中的某一行進行插入、刪除、更新時觸發某一觸發器來執行某些操作
觸發條件
insert 在插入表的時候觸發
update 在更新表的時候觸發
delete 在刪除表的時候觸發
觸發時機
before 在…之前
after 在…之後
數據庫一共有六種觸發器,分別爲:
before insert #在數據插入之前
after insert #在數據插入之後
before update #在數據更新之前
after update #在數據更新之後
before delete
after delete
例如:利用觸發器實現檢查約束 check
對於下表創建一個觸發器,規定年齡不能低於0歲且不能高於100歲,低於0歲的用0代替,高於100歲的用100代替。
創建表格
create table test_tb(
id int primary key auto_increment,
age decimal(3,0) #decimal是一種浮點型,可規定小數位數
);
創建觸發器
create trigger tir_test1_insert
before insert on test1 for each row
begin
if new.age < 0 then set new.age = 0;
elseif new.age >100 then set new.age = 100;
end if;
end;
創建一個觸發器,實現上述功能
對象new和old
數據庫給觸發器提供了兩個對象 new 和 old 分別記錄新值和舊值
,例如:update更新數據時會把新的數據覆蓋之前的數據,那new對象就是保存的新數據,而old對象是保存被覆蓋之前的數據。
那麼相對於insert而言是沒有old的,因爲插入之前是沒有舊數據
相對於delete而言是沒有new的,只刪除原來存在的數據,不添加新數據
new:當觸發插入和更新事件時可用,指向的是被操作的記錄
old: 當觸發刪除和更新事件時可用,指向的是被操作的記錄
insert 插入時 new 表示插入的數據
update 更新時,new表示新的數據,old表示的是原數據
delete 刪除時, old 表示的是刪除的數據
觸發器在 8.0 以上的新版本中不允許使用臨時表,也就是不允許寫上 select 語句
查看觸發器
MySQL觸發器都是存在 information_shema.triggers 表中的,所以查看觸發器需要查詢information_shema 數據庫中的 trigger 表.
# 查看所有觸發器
show triggers from 數據庫;
刪除觸發器
drop trigger 觸發器名;
drop trigger student_ins;
使用觸發器製作日誌
創建日誌表
create table review_tb (
id int primary key auto_increment,
username varchar(64),
action_name varchar(20),
actiom_time datetime
)engine innodb default charset utf8;
創建觸發器
create trigger test_review_insert
after insert
on test1 for each row
begin
insert into review values(null,user(),'insert',now());
end;
觸發器的使用限制
不是任何語句都可以用觸發器來執行的
- 觸發器不能使用存儲過程和函數,也不能使用select和call等動態的sql語句。
- 觸發器中不能使用開始和結束事務。
- 觸發器不能寫得太複雜,否則沒改變一行,所執行的任務就太多了。
利用錯誤突破使用限制
雖然觸發器中不能使用select查詢數據,不能直接通過參數返回,但是可以通過用戶變量帶回數據。
例如:創建觸發器帶回一個參數
create trigger test_review_id
after insert on test1 for each row
begin
select new.age from test1
where new.id = id into @ages;
end;
select @ids;
另外,觸發器中只要有一條語句出現錯誤,整個觸發器就不會執行。
如:
create trigger test_review_idname
after insert on test1 for each row
begin
select new.id from test1 into @ids;
select new.action_name from test into @actions;
select '錯誤';#這裏的@ids和@actions值會是什麼?
end;
select @ids; #這裏的@ids和@actions值沒有被改變
select @actions; #這就是事務處理,利用錯誤實現回滾
事件
事件的基本概念
與觸發器類似,都是在特定的條件執行相應的操作,
但是不同的是,觸發器是觸發時執行任務,而事件是定時執行任務的。
- 事件關鍵字: event
- 基本作用:讓數據庫定時執行某些操作。
事件的創建
可以通過 ? create event 命令查看創建觸發器的格式。
#if not exists不存在就創建
create event [if not exists] 事件名稱
ON schedule #計劃任務
(定時操作:AT timestamp 時間點,EVERY interval 間隔多久)
[ON COMPLETION [NOT] PRESERVE] # 事件到期處理
(事件執行完之後默認保留,加一個NOT爲刪除)
[enable | disable | disable on slave] #事件的狀態
(開啓 | 關閉) #相當於你設置的鬧鐘是打開還是關閉的
[COMMENT 'string'] # 這是註釋,不用管
DO event_body; # 執行的操作
schedule: # 任務計劃參數解析
AT timestamp [+ INTERVAL interval] ...
# AT 時間點 [+ 時間間隔]
(如:AT 2020-6-6 8:30:10,2020年6月6號8點30分10秒)
| EVERY interval
[STARTS timestamp [+ INTERVAL interval] ...]
[ENDS timestamp [+ INTERVAL interval] ...]
創建事件的流程
create event [if not exists] 事件名
on schedule 執行的操作 時間點 ##執行的操作: every | at
[starts] 時間點 ##到什麼時間開始
[ends] 時間點 ##到什麼時間結束
do
語句操作
every 間隔多久
- start [開始時間 [+ 時間間隔]]
- end [結束時間 [+ 時間間隔]]
current_timestamp 開啓時間
時間計算操作
interval 1 day + interval 30 second;
例如:對於以下表,創建一個事件,每隔6秒鐘自動插入一條數據。
4. 創建事件測試表
create table event_table (
id int primary key auto_increment,
insert_time datetime
)engine innodb default charset utf8;
select * from event_table; # 查看錶中數據
4.創建一個事件,每隔6秒自動插入一條數據
create event insert_event
on schedule every 6 second
do
insert into event_table values(null,now());
#這裏只有一條語句可以不用begin end;
查看事件
查看所有事件的狀態
show events;
事件調度器
事件是由事件調度器管理的,所以需要打開事件調度器才能執行事件。
- 查看事件調度器的狀態 #事件調度器狀態是一個會話變量
show variables like '%SCHEDULE%';
- 設置事件調度器的的狀態 # 通過會話變量打開或關閉
set global event_scheduler = on; # 或者=1,打開調度器
set global event_scheduler = off; # 或者=0,關閉調度器
- 查看進程列表
事件調度器開啓後是有由一個進程來執行的
show processlist; # 查看進程列表
小練習:每隔一分鐘清空表數據
create event truncate_event
on schedule
every 1 minute
do
truncate table event_table;
單獨開啓/禁用某個事件
開啓和關閉事件調度器會使所有的事件都同時開啓或關閉,那如何對單個事件進行開啓或關閉呢?
- 單獨禁用某個事件
alter event insert_event disable; - 單獨開啓某個事件
alter event insert_event enable;
事件調度器像是一個總開關而每個單獨的事件都有一個自己獨立的開關
#刪除表格內所有的數據
#這種刪除方式比delete快,但是不能進行where篩選
truncate table 表格名稱
小練習1:創建一個清空表事件,7天之後開啓事件,每天清空表,一個月後停止並刪除事件。
create event clear1_event
on schedule
every 1 day # 每隔1天
starts current_timestamp + interval 7 day # 7天后開啓
ends current_timestamp + interval 1 month # 1月後停止
on completion not preserve # 停止後不保留事件
do
truncate table event_table;
小練習2:創建一個清空表事件,固定時間點清空表數據
create event clear2_event
on schedule
at '2020-3-15 23:59:59' + interval 3 day # 固定時間點
do # 可用interval關鍵字加上間隔時間
truncate table event_table;
MySql時間單位
數據庫中的時間單位有:year年、month月、day日、week星期、hour小時、minute分鐘、second秒鐘、microsecond微秒。
second 秒
minute 分
hour 時
day 天
month 月
year 年
事件刪除
drop event 事件;
查看事件的具體執行語句
show create event 運行的事件;
總結 觸發器
- 通過觸發器對增刪改進行邏輯操作
通過觸發器進行數據備份
進行事務監控 - 事件
每隔一段時間執行固定的操作
製作一個定時器