我知道这可能看起来像一个奇怪的问题......
我有一个第 3 方数据库和服务,我想通过每个表上INSERT
的DML 触发器来监视它。UPDATE
DELETE
但是,唉,我在TRUNCATE TABLE
调用时遇到了问题,因为它没有激活DELETE
触发器。
我正在寻找一种“超载”的方法,TRUNCATE TABLE
就像:
DELETE FROM X; --remove all rows
TRUNCATE TABLE X; --truncate the empty table
或者也许在截断之前激活一些 DDL 触发器,这样我就可以检查哪些行将被截断。
如果还有其他建议,我会很高兴。
这样的事情可能吗?
编辑
我不想禁用truncate
我只想监视数据。
它是第 3 方数据库,它被我无法控制的服务使用,所以我无法阻止truncate
.
我只是想监控变化,目前无法跟踪由truncate
命令引起的记录删除。
谢谢!
当您从表中删除时,您正在删除行。
WHERE
您可以使用子句指定要删除的行。当您TRUNCATE
创建一个表时,它不会记录删除了哪些行,并且会执行最少的日志记录。TRUNCATE
是清除表而不会导致事务日志膨胀的好方法。您不需要触发器。A
TRUNCATE
将删除表中的所有行,您知道在此过程中将删除所有行。没有幸存者。如果您想捕获事件以了解谁截断了什么或何时截断,您可以使用 SQL 审计来完成此操作,如Mohd Sufian 在 SQL Ship 上所示。
我不相信您可以从 a 触发触发器
Truncate
,这里是MSDN上的 DDL 列表,其中列出了可以从触发器触发的 DDL 事件。您还可以使用扩展事件来捕获
Truncate
事件,正如Jonathan Kehayias 在 MSDN 上展示的那样。如果你想阻止用户运行
Truncate
,你可以创建一个视图或另一个对象SCHEMABINDING
。这可以防止 DDL 语句更改有问题的表,其中包括Truncate
.最后要注意的
Truncate
是,如果您有标识列,它将重新设置值。我见过人们一起使用该RESEED
功能Truncate
。他们将捕获最后使用的身份,将其存储到一个变量表中,截断表以最少的日志记录删除所有记录并重置身份列,然后重新播种最后一个增量。通常如果你截断,你不关心重新播种。(并非总是如此,但通常如此。)我主要在暂存表或需要重置实例以进行测试时进行截断。我很少以其他方式截断表,因为我关心引用数据的完整性以及从表中删除了哪些行。当我都不关心时,我会截断。
我强烈建议阅读更多关于
Delete
和的内容Truncate
,它们将取得相似的结果,但却是两件截然不同的事情。MSSQLTips 上的 Atul Gaikwad 写了一篇关于其中一些差异的不错的快速文章。
现在我们来看这个问题:
理想情况下,截断事件是预定的或可以计划的。更理想的是,您将能够更改代码或添加一些内容,以便它可以为您记录信息。根据您的帖子,我假设您无法计划、安排或更改代码。
那么,如果必须的话,您如何绝对确定地跟踪哪些行将受到截断的影响?
我个人会创建两个表、一个触发器和一个过程。
触发器将基于插入或删除任务,它会将受影响的行数、表名和日期时间插入表中。因此,如果您的进程插入了 6 行,触发器将插入值 6,表示有 6 条新记录流入。如果您删除了 10 行,它会插入值 -10,表示现在有 10 条记录消失了。
我想为笔记或事件创建一个额外的列。我希望审计或扩展事件在截断发生的日期/时间记录到该表。他们无法告诉您有多少行,但可以告诉您何时何人。这才是此时此刻真正重要的。
第二张表将是第一张表的汇总,因为我假设您一天可能有很多交易。这会告诉您当天结束时的净记录总数,还会告诉您截断发生的时间。这意味着您会知道在截断之前表中有多少记录,满足您的要求。
该过程将在表之间进行聚合,并且还将对第一个表执行清理工作。