SHR*_*SHR 5 sql-server truncate
我知道这可能看起来像一个奇怪的问题......
我有一个第三方数据库和服务,我想通过在DML触发器对其进行监视INSERT
,UPDATE
并且DELETE
每个表的。
但是,唉,我在TRUNCATE TABLE
被调用时遇到了问题,因为它没有激活DELETE
触发器。
我正在寻找一种“重载”的方法TRUNCATE TABLE
,例如:
DELETE FROM X; --remove all rows
TRUNCATE TABLE X; --truncate the empty table
Run Code Online (Sandbox Code Playgroud)
或者在截断之前激活一些 DDL 触发器,这样我就可以检查哪些行将被截断。
如果还有其他建议,我会很高兴。
这样的事情可能吗?
编辑
我不想禁用truncate
我只想监视数据。
它是第 3 方数据库,并且被我无法控制的服务使用,因此我无法阻止truncate
.
我只是想监视更改,目前无法跟踪由truncate
命令引起的记录删除。
谢谢!
我正在寻找一种“重载” TRUNCATE TABLE 的方法,例如:
从 X 中删除;--删除所有行 TRUNCATE TABLE X; --截断空表
从表中删除时,就是在删除行。您可以使用WHERE
子句指定要删除的行。当您创建TRUNCATE
一个表时,它不会记录删除了哪些行,并且会执行最少的日志记录。TRUNCATE
是清除表而不导致事务日志膨胀的好方法。
或者在截断之前激活一些 DDL 触发器,这样我就可以检查哪些行将被截断。
为此,您不需要触发器。ATRUNCATE
将删除表中的所有行,您知道所有行都将在此过程中被删除。没有幸存者。
如果您想捕获事件以了解谁截断了什么或何时截断,您可以使用 SQL 审计来完成,如Mohd Sufian 在 SQL Ship 上所示。
我不相信您可以从触发器中触发触发器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 条记录消失了。
我想为笔记或事件创建一个额外的列。我希望审计或扩展事件在截断发生的日期/时间记录到此表中。他们将无法告诉您有多少行,但它可以告诉您何时以及何人。这才是此刻真正重要的。
第二个表将是第一个表的汇总,因为我假设您一天内可能有很多交易。这将告诉您一天结束时的净记录总数,并告诉您何时发生截断。这意味着您将知道在截断之前表中有多少记录,满足您的要求。
该过程将在表之间进行聚合,并且还将对第一个表执行清理工作。