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