# 使用statement trigger 檢查delete 是否有where條件 ## 前言 之前有分享過使用trigger 保護的table不能delete或update.[按我前往](https://hackmd.io/@pgsql-tw/BJNU4QDYd) 也有搭配JSON保存資料的方式.[按我前往](https://hackmd.io/@pgsql-tw/SJ11Mwy2o) 也有一些其他方式的分享,例如保護並發送telgram訊息的方式.在此不一一列舉.有興趣的朋友,可以看 [PostgreSQLTW_HackMD](https://hackmd.io/team/pgsql-tw?nav=overview) 在HackMD的分享資料. 不久前MySQL User Group Taiwan有一篇有意思的分享.[按我前往](https://www.facebook.com/groups/taiwanmysqlusergroup/posts/2602678366546559) 會出現一些提示語. 之前分享的方式,大多是純保護,這次增加判斷是否有where 條件. 並使用statement 層級,避免出現過多訊息. ## 來看展示吧 ```sql= create schema s0125; create table s0125.tbl1 ( id int not null primary key , gal text ); insert into s0125.tbl1 values (1, '宇都宮しをん'),(2, 'RION'), (3, '安齋らら'); create or replace function s0125.thinkabout() returns trigger language plpgsql as $code$ begin if ( current_query() !~* 'where' ) then raise exception '兄弟別衝動! 想想 %', (array['父母', '孩子', '小島南', '河北彩花'])[(mod(ceil(random()*10)::int, 4) + 1)]; return null; else return new; end if; end; $code$; create trigger tri_bd_tbl1 before delete on s0125.tbl1 for each statement execute function s0125.thinkabout(); -- 注意是 statement trigger delete from s0125.tbl1; ERROR: P0001: 兄弟別衝動! 想想 河北彩花 CONTEXT: PL/pgSQL function s0125.thinkabout() line 4 at RAISE LOCATION: exec_stmt_raise, pl_exec.c:3907 Time: 1.197 ms bunko666[bunko666]#* select * from s0125.tbl1; id | gal ----+-------------- 1 | 宇都宮しをん 2 | RION 3 | 安齋らら (3 rows) Time: 0.321 ms bunko666[bunko666]#* delete bunko666-*# from s0125.tbl1; ERROR: P0001: 兄弟別衝動! 想想 父母 CONTEXT: PL/pgSQL function s0125.thinkabout() line 4 at RAISE LOCATION: exec_stmt_raise, pl_exec.c:3907 Time: 0.492 ms bunko666[bunko666]#* delete bunko666-*# from s0125.tbl1; ERROR: P0001: 兄弟別衝動! 想想 小島南 CONTEXT: PL/pgSQL function s0125.thinkabout() line 4 at RAISE LOCATION: exec_stmt_raise, pl_exec.c:3907 Time: 0.430 ms bunko666[bunko666]#* rollback; ROLLBACK ``` ## 就是要刪除 ```sql= delete from s0125.tbl1 where true; DELETE 3 select * from s0125.tbl1; id | gal ----+----- (0 rows) ``` 只要有where 條件,就可以動作了. 這樣就可以避免,沒有使用where時不小心刪除全部資料. ## 結語 結合之前一些例子,我們可以搭配使用,做很多保護或者保存後還原. ## 感謝 感謝 河北彩花,小島南以及宇都宮三姐妹.