如何确保在SQL Server中不会意外删除行?

时间:2010-09-16 19:22:59

标签: sql-server sql-server-2008

在我的数据库中,我有一些对应用程序运行很重要的数据(常量,......)。我有通过测试网站生成的测试数据。由于测试数据是可消耗的,因此会定期删除它。不幸的是,这两种类型的数据出现在同一个表中,因此我无法执行delete from T,但我必须执行delete from T where IsDev = 0

如何通过忘记放入过滤器来确保不会意外删除非开发数据?如果发生这种情况,我必须从生产备份中恢复,这会浪费我的时间。我需要某种外键,例如在满足某个条件时无法删除的行为。这对于确保我的代码不会因为错误而做任何有害的事情也很有用。

7 个答案:

答案 0 :(得分: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

我猜错了语法,但你明白了。

答案 1 :(得分:2)

我会使用触发器。

答案 2 :(得分:1)

在单独的管理表中保留要保留的行的备份

答案 3 :(得分:1)

似乎你需要一个关于删除操作的触发器,如果​​它看到它是一个永远不应删除的行,那么它将查看row和rollback事务。

另外,您可能需要阅读这篇文章:Prevent accidental update or delete commands of all rows in a SQL Server table

答案 4 :(得分:1)

根据您想要的透明程度,您可以使用INSTEAD OF触发器,它始终记住您的WHERE。

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

答案 5 :(得分:1)

我建议不要每次都从头开始编写delete语句,只需创建一个存储过程来执行删除并执行删除语句。

create procedure ResetT as delete from T where IsDev = 0

答案 6 :(得分:1)

您可以在表中创建一个额外的列IS_TEST,将TABLE_NAME重命名为TABLE_NAME_BAK,并在TABLE_NAME_BAK上创建一个视图TABLE_NAME,以便只显示设置了IS_TEST的行。对于要保留的数据,将IS_TEST设置为零,并将DEFAULT 1添加到IS_TEST列应该完成作业。它类似于创建“软删除”所需的过程。