2010-09-16 106 views
3

在我的數據庫中,我有一些對應用程序運行很重要的數據(常量,...)。我有通過測試網站生成的測試數據。由於測試數據是可消耗的,因此定期刪除它。不幸的是,這兩種類型的數據出現在同一張表中,所以我不能做delete from T,但我必須做一個delete from T where IsDev = 0如何確保在SQL Server中不會意外刪除一行?

如何確保我不會意外刪除非開發數據而忘記放置過濾器?如果發生這種情況,我必須從正在浪費時間的生產備份中恢復。我會需要某種外鍵,例如在滿足某些條件時無法刪除的行爲。這對確保我的代碼不會因爲錯誤而不會造成任何有害影響也很有用。

回答

8

嗯,你可以使用拋出異常的觸發器如果任何在deleted元表中的記錄有IsDev = 1

CREATE TRIGGER TR_DEL_protect_constants ON MyTable FOR DELETE AS 
BEGIN 
    IF EXISTS(SELECT 1 FROM deleted WHERE IsDev <> 0) 
    BEGIN 
     ROLLBACK 
     RAISERROR('Can''t delete constants', 1, 16) 
     RETURN 
    END 
END 

我猜對語法了一點,但你明白了。

+0

我會在'RAISERROR'之後添加一個'RETURN',以確保觸發器執行在那裏結束 – 2010-09-16 19:30:19

+0

啊非常好。 。 – usr 2010-09-16 19:31:30

+0

良好的通話,@KM。我也想知道OP是否意味着IsDev <> 1,但人們對術語有不同的看法。 – harpo 2010-09-16 19:32:25

1

保留要保留在單獨的管理表中的行的備份

1

根據您想如何透明,使這個,你可以使用一個INSTEAD OF觸發器將永遠記住你的什麼地方。

CREATE TRIGGER TR_IODEL_DevOnly ON YourTable 
INSTEAD OF DELETE 
AS 
BEGIN 
    DELETE FROM t 
     FROM Deleted d 
      INNER JOIN YourTable t 
       ON d.PrimaryKey = t.PrimaryKey 
     WHERE t.IsDev = 0 
END 
1

我建議,而不是從頭開始,每次寫delete語句,只需創建一個存儲過程來完成的缺失和執行。

create procedure ResetT as delete from T where IsDev = 0 
+0

理論上,當然。實際上,有一天有人會忘記使用proc的重要性。然後......最好用觸發器來掩護自己。 – 2010-09-16 20:24:34

+0

@Joe Stefanelli - 這就是爲什麼存儲過程應該是唯一有權從表中刪除的實體。觸發器是編寫良好的代碼和訪問限制的好替代品。 – 2010-09-16 20:31:10

+0

查詢並不總是相同的。有時我會刪除一部分數據。 – usr 2010-09-18 12:38:16

1

你可以在你的表中創建一個額外的列IS_TEST,重命名TABLE_NAME到TABLE_NAME_BAK,並讓只有在IS_TEST設置行顯示在它的TABLE_NAME_BAK創建視圖TABLE_NAME。將IS_TEST設置爲零以保留要保留的數據,並將DEFAULT 1添加到IS_TEST列應完成該作業。它與創建「軟刪除」所需的過程類似。

相關問題