一般来说,我们未来阻止用户删除或者清空表以及数据, 可以直接从权限下手,给他少量的权限即可。 
比如,防止用户进行truncate 操作, 可以给如下权限:

点击(此处)折叠或打开

  1. t_girl=# create role ytt3 with login connection limit 1 password 'ytt3';
  2. CREATE ROLE
  3. t_girl=# alter schema ytt owner to ytt3;
  4. ALTER SCHEMA
  5. t_girl=# grant select on all tables in schema ytt to ytt3;
  6. GRANT



现在用新用户ytt3登陆并且执行TRUNCATE,发现被禁止。

点击(此处)折叠或打开

  1. bash-4.1$ psql -U ytt3 t_girl
  2. psql (9.3.4)
  3. Type "help" for help.
  4. t_girl=> truncate table j2;
  5. ERROR: permission denied for relation j2





但是当测试的时候,一般来说,管理员为了方便懒得去分配各种各样细的权限。 那么,我们在创建表的时候, 就得给这张表来做对应的限制。当然了,生产环境不建议这么做。
这个实现就比较简单了,创建一个基于语句的触发器就OK了。

点击(此处)折叠或打开

  1. t_girl=# \sf prevent_truncate
  2. CREATE OR REPLACE FUNCTION public.prevent_truncate()
  3.  RETURNS trigger
  4.  LANGUAGE plpgsql
  5. AS $functio$
  6. BEGIN
  7. RAISE EXCEPTION 'Prevent "%" to be truncated!', TG_TABLE_SCHEMA||TG_TABLE_NAME;
  8. RETURN NEW;
  9. END;
  10. $function$


  11. t_girl=# \d j2
  12.         Table "ytt.j2"
  13.  Column | Type | Modifiers
  14. --------+---------+-----------
  15.  id | integer |
  16.  str2 | text |
  17. Triggers:
  18.     trigger_truncate_before BEFORE TRUNCATE ON j2 FOR EACH STATEMENT EXECUTE PROCEDURE ytt.prevent_truncate()


  19. t_girl=#






点击(此处)折叠或打开

  1. t_girl=# truncate table j2;
  2. ERROR: Prevent "ytt.j2" to be truncated!




这种方法也只是对于提供了这项功能的数据库才OK。 比如MySQL的触发器只提供了基于行的操作,那么语句的操作就不能触发了。 所以如果在MySQL上来实现这点,就比较麻烦。要么,就从权限入手,

点击(此处)折叠或打开

  1. mysql> truncate table j2;
  2. ERROR 1142 (42000): DROP command denied to user 'ytt3'@'localhost' for table 'j2'


要么,就对数据库的操作用SPROC封装起来,

点击(此处)折叠或打开

  1. +------------------------------------+
  2. | Error |
  3. +------------------------------------+
  4. | Prevent t_girl.j2 to be truncated! |
  5. +------------------------------------+
  6. 1 row in set (0.00 sec)


02-05 16:53