一种SqlServer防止误删全表的触发器设置方法

1.设计思路说明

0.通过一个统计表,用来记录你的关键业务表的记录数;每次进行删除操作时,通过创建设置的触发器,检索你当前操作会造成影响记录行数和统计表种对应的记录数进行比对,如果两者相等或者你的基础统计表没有初始化记录数,则回滚事务。然后,触发器承担着更新统计表对应记录数的职责。
1.创建一个统计表,用来记录你的行记录,比如我的表名叫“T_WS_FUNC_FORBIDDELTABLE”,字段包含TABLENAME(varchar),NUM_RECORD(bigint),TIME_CHANGE(datetime)。TABLENAME存储你的关键业务表名,NUM_RECORD表示关键业务表的记录数。
2.创建如下触发器,详情见代码注释。

2.触发器 实现具体代码

USE [ASRS_ZZ_ZT_1]
GO
/****** Object:  Trigger [dbo].[TR_TRANS_A_DI_LPT]    Script Date: 2019/4/11 0:09:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--Date:2019-4-10,2019-4-11
--Author:LJS,LJS
--Description:       1.禁止数据表[T_TRANS_LOG_PALLETID_TRACK]删除全部数据记录;
--                   2.记录删除/插入操作后,[T_TRANS_LOG_PALLETID_TRACK]表的数据行数;
CREATE TRIGGER [dbo].[TR_TRANS_A_DI_LPT] ON  [dbo].[T_TRANS_LOG_PALLETID_TRACK]
AFTER DELETE ,INSERT
AS
DECLARE @V_COUNT BIGINT
DECLARE @V_NUM_DEL    BIGINT
DECLARE @V_NUM_RECORD BIGINT
BEGIN
       --1.禁止数据表[T_TRANS_LOG_PALLETID_TRACK]删除全部数据记录;
       SELECT @V_NUM_DEL = COUNT(*) FROM deleted; 
       SELECT @V_NUM_RECORD = ISNULL(NUM_RECORD,0) FROM T_WS_FUNC_FORBIDDELTABLE WHERE TABLENAME='T_TRANS_LOG_PALLETID_TRACK';
       --@V_NUM_DEL =0,即没有删除任何数据行时,触发器不起作用(避免当表的数据记录为0,@V_NUM_DEL[数值为0]=@V_NUM_RECORD[数值为0]触发器报错)
       --@V_NUM_DEL =1,即删除仅有的一行数据时,触发器不起作用(避免当表的数据记录为1,@V_NUM_DEL[数值为1]=@V_NUM_RECORD[数值为1]触发器报错)
       --如果是INSERT操作,则@V_NUM_DEL值为0,因此则会跳过涉及DELETE ALL的逻辑程序块(即@V_NUM_DEL>1执行的程序语句)
       IF @V_NUM_DEL > 1 BEGIN
              --逻辑:   数据表删除全部数据记录的(危险)操作
              --等价于  (不限制数据结果集=1时的删除操作)删除当数据表数据记录结果集大于1,要删除的结果集>1,数据表数据记录结果集=要删除的结果集
              --等价于  要删除的结果集>1,数据表数据记录结果集=要删除的结果集
              --描述:   判断要删除的数据行记录行数等于表的数据记录行数,则认为是DELETE FROM T_TRANS_LOG_PALLETID_TRACK语句没有通过WHERE语句进行范围限制.
              IF @V_NUM_DEL = @V_NUM_RECORD OR @V_NUM_RECORD =0 BEGIN       
                RAISERROR('你是疯了吗?确定数据表[T_TRANS_LOG_PALLETID_TRACK]删除全部数据记录?',1,1)
                    ROLLBACK TRANSACTION
              END
       END
       --2.记录删除/插入操作后,[T_TRANS_LOG_PALLETID_TRACK]表的数据行数;如果是删除全部数据记录,则经过1的否决判断,行数保持不变;
        --T_WS_FUNC_FORBIDDELTABLE 表的基本结构:TABLENAME(表名)|NUM_RECORD(行记录数量)
       SELECT @V_COUNT=(SELECT COUNT(*) FROM T_TRANS_LOG_PALLETID_TRACK);
       UPDATE T_WS_FUNC_FORBIDDELTABLE
       SET NUM_RECORD = @V_COUNT,TIME_CHANGE=GETDATE()
       WHERE TABLENAME ='T_TRANS_LOG_PALLETID_TRACK'
       
END 

这样,当你不小心执行DELETE FROM 不加WHERE的操作时,就能避免悲剧和麻烦的发生。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值