2013-09-25 65 views
1

大约每年5次,我们最关键的表中有一个特定列,其中所有值都替换为NULL。我们已经运行了日志浏览器,并且我们看不到任何使用更新填充的登录名/主机名,我们只能看到记录已更改。我们已经搜索了我们所有的sprocs,函数等,以查看在我们服务器上的所有数据库上触及此表的所有更新语句。该表在此列上具有外键约束。它是在更新期间建立的整数值,但更新是特定于标识键的。这个领域也有一个索引。任何关于什么可能导致t-sql更新声明以外的建议?SQL 2008表中列中的所有记录已更新为NULL

+0

你是用一些脚本升级/迁移数据库吗? –

回答

1

我会开始拒绝任何客户端动态SQL,如果可能的话。审计存储过程以确保它们执行正确的sql(包括适当的where子句)要容易得多。除非你的SQL服务器非常糟糕,否则他们只会更新数据,因为你运行的是SQL。

所有存储的特效卡,脚本等都应在被允许运行之前进行审计。

如果您没有强制执行动态客户端sql的mojo,请在执行之前添加捕获每个客户端sql的应用程序日志记录。就我个人而言,当缺少where子句时,我会让日志记录例程(在记录日志之后)抛出一个异常,但至少应该能够通过查看日志来找出数据下次被清除的位置。确保您的日志捕获足够的信息,您可以将其追溯到确切的来源。为每个可能执行的动态sql语句分配一个唯一的“名称”,例如,每个程序分配一个3个字符的代码,然后在程序中为每个可能的1..nn调用编号,以便知道哪个调用会在“abc123”以及有缺陷的确切sql。

添加评论

想到了这一点。您可能能够在sql表上添加/修改更新触发器来查看行数,如果行数超过适合您的阈值,更新阻止更新。所以,做了一点搜索,发现有人wrote an article这个已经在这个片段中

CREATE TRIGGER [Purchasing].[uPreventWholeUpdate] 
ON [Purchasing].[VendorContact] 
FOR UPDATE AS 
BEGIN 
    DECLARE @Count int 
    SET @Count = @@ROWCOUNT; 

    IF @Count >= (SELECT SUM(row_count) 
     FROM sys.dm_db_partition_stats 
     WHERE OBJECT_ID = OBJECT_ID('Purchasing.VendorContact') 
     AND index_id = 1) 
    BEGIN 
     RAISERROR('Cannot update all rows',16,1) 
     ROLLBACK TRANSACTION 
     RETURN; 
    END 
END 

虽然这不是真正正确的修复,如果适当地记录此,我敢打赌,你可以找出试图重振旗鼓你的数据并修复它。

最好的运气

0

事务日志资源管理器应该能够看到谁执行的命令,何时以及如何具体命令如下。

您使用哪个日志资源管理器?如果您使用ApexSQL Log,则需要启用连接监视功能才能捕获其他登录详细信息。

0

这可能就像使用大锤驾驶大拇指一样,但是您是否考虑过使用SQL Server审计(假设您使用的是SQL Server Enterprise 2008或更高版本)?

相关问题