# 使用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時不小心刪除全部資料.
## 結語
結合之前一些例子,我們可以搭配使用,做很多保護或者保存後還原.
## 感謝
感謝 河北彩花,小島南以及宇都宮三姐妹.