假设我想从数据库中删除一个名为“abc cba”的用户。所以我运行以下查询:
DELETE FROM table WHERE fname = 'abc' AND last name = 'cba'; commit;
现在,可以有更多我不知道的这个名字的用户。显而易见的选择是事先运行 select 语句并检查我是否正在删除我真正想删除的内容,但我仍然是人,我可以忘记这一点并最终搜索备份以检索丢失的数据。
我的问题是:有没有办法对语句施加某些规则,之后它们将不会执行 DML 语句(例如,如果删除的行数超过某个阈值,则不执行删除)?
我只能代表 SQL Server,但唯一可以做到这一点的方法是通过 DML 触发器(据我所知)。以下面的例子:
不过这种方法存在一些问题,我认为这不是一个好的设计。首先,您在触发器中有硬编码的要求(无论您是在设置行数还是行的百分比......它仍然是硬编码的)。必须相应地设计应用程序以确保使用不同的逻辑进行重试。
这真正归结为拥有正确设计的数据库和正确构造的 DML 语句,以确保正在修改的数据是您想要的数据,而不必检查已删除行的行数。
在我看来,你应该花设计时间来弄清楚如何重新设计,这样你就不需要这个检查了。
就资源而言,在数据库级别强加此类规则可能非常昂贵,因此我认为没有一种适用于所有地方的标准方法。
我没有什么比在 trigger 体内
BEFORE DELETE
引发错误更好的建议了(或者AFTER DELETE
,但BEFORE
在这种情况下 trigger 似乎更合适)。不幸的是,它非常依赖于 RDMS。例如,在Oracle中,如果你想在触发器内访问同一张表,你需要使用语句级触发器;SQLServer 调用此类触发器INSTEAD OF
,而不是BEFORE
。