【问题标题】:Setup a Trigger on Table to limit the number of INSERT, DELETE, UPDATE Operations在 Table 上设置触发器以限制 INSERT、DELETE、UPDATE 操作的数量
【发布时间】:2020-06-08 00:48:05
【问题描述】:

例如:用户在特定表上执行INSERT、DELETE 和UPDATE 操作的次数不应超过X 次在给定时间点,如果用户执行操作 X+1 次,则会启动触发器。

【问题讨论】:

  • TRIGGER 不是这样工作的。每次与触发器相关的 DML 针对TRIGGER 所属的对象运行时,TRIGGER“触发”。但这闻起来像XY Problem。为什么您要在一秒钟内阻止用户执行说 20 个INSERT 语句(每个影响 1 行),但允许他们处理 3 个每个影响 10,000 个的语句?还是您纯粹是想阻止人们使用 RBAR 操作?如果是这样,请教他们如何编写基于集合的 SQL。
  • 实现此场景的目的是限制用户查询可以在表中修改的记录数。这是为了避免错误地或有意地对表进行大规模更新。例如,用户将无法对特定表运行批量 UPDATE 查询或 DELETE 查询
  • 老实说,这似乎更像是员工应该在他们(愚蠢地)写像UPDATE YourTable SET IsActive = 0 WHERE IsActive = 1;这样的声明之前检查他们的工作。这与INSERT though 有什么关系?
  • 这听起来像是寻找问题的解决方案。
  • 我们都可以承认(即使是我们这些有经验的人)我们有时会运行这样的查询,但这就是为什么开发和登台环境,并首先用 SELECT 替换 UPDATE太重要了;以便您知道要更新/删除的内容。

标签: sql-server triggers ssms dml


【解决方案1】:
create table dbo.targetTable
(
    id int,
    colA varchar(10)
);
go
create or alter trigger dbo.DMLxTimes on dbo.targetTable
for insert, update, delete
as
begin
    /*
        --old days..
        IF @@ROWCOUNT > 5
        begin
            rollback;
        end
    --*/

    declare @maxrows int = 5; --maximum number of rows allowed per dml action

    if 
    (select count(*) from inserted) > @maxrows
    or
    (select count(*) from deleted) > @maxrows
    begin
        rollback;
    end
end
go

insert into dbo.targetTable(id, colA)
values (0, 'a'),(0, 'a'),(0, 'a'),(0, 'a'),(0, 'a'); --5 rows inserted
go
insert into dbo.targetTable(id, colA)
values (0, 'a'),(0, 'a'),(0, 'a'),(0, 'a'),(0, 'a'),(0, 'a'); --6 rows inserted ... error
go
insert into dbo.targetTable(id, colA)
values (0, 'a'),(0, 'a'); --2 rows inserted
go

--all updated, error
update dbo.targetTable
set colA = colA;
go

--ok
update top(5) dbo.targetTable
set colA = colA;
go

delete top (4) from dbo.targetTable;
go

--ok
update top(15) dbo.targetTable
set colA = colA;
go

【讨论】:

  • 我个人建议在触发器中使用THROW 而不是ROLLBACK。事务的处理应该在触发器之外完成,你也可以传递一个有用的错误。
猜你喜欢
  • 2022-01-27
  • 2013-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多