2013-09-25 66 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或更高版本)?

相關問題