在我的数据库中,我有一些对应用程序运行很重要的数据(常量,......)。我有通过测试网站生成的测试数据。由于测试数据是可消耗的,因此会定期删除它。不幸的是,这两种类型的数据出现在同一个表中,因此我无法执行delete from T
,但我必须执行delete from T where IsDev = 0
。
如何通过忘记放入过滤器来确保不会意外删除非开发数据?如果发生这种情况,我必须从生产备份中恢复,这会浪费我的时间。我需要某种外键,例如在满足某个条件时无法删除的行为。这对于确保我的代码不会因为错误而做任何有害的事情也很有用。
答案 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列应该完成作业。它类似于创建“软删除”所需的过程。