SQL 2008表中列中的所有记录都更新为NULL

时间:2013-09-25 20:08:34

标签: sql-server null sql-update

一年大约5次,我们最关键的一个表有一个特定的列,其中所有值都替换为NULL。我们已针对此运行日志浏览器,我们无法看到任何登录/主机名填充更新,我们可以看到记录已更改。我们搜索了所有的sprocs,函数等,以查找在我们服务器上的所有数据库上触及此表的任何更新语句。该表在此列上具有外键约束。它是在更新期间建立的整数值,但更新是特定于标识密钥的。该领域还有一个索引。有关在t-sql更新语句之外可能导致此问题的任何建议吗?

3 个答案:

答案 0 :(得分:1)

我会首先拒绝任何客户端动态SQL,如果可能的话。审计存储过程要确保它们执行正确的sql包括正确的where子句要容易得多。除非您的sql服务器严重损坏,否则它们只会更新数据,因为您正在运行它的SQL。

在允许运行之前,应审核所有存储过程,脚本等。

如果您没有mojo来强制执行没有动态客户端sql,请添加在执行之前捕获每个客户端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

虽然这不是真正正确的解决方案,但如果你恰当地记录下来,我打赌你可以弄清楚是什么试图弄乱你的数据并修复它。

祝你好运

答案 1 :(得分:0)

事务日志资源管理器应该能够查看执行命令的人员,时间以及命令的具体方式。

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

答案 2 :(得分:0)

这可能就像使用大锤开车一样,但您是否考虑使用SQL Server审核(假设您使用的是SQL Server Enterprise 2008或更高版本)?