进行逻辑删除时保持一致性

时间:2014-07-31 15:07:40

标签: sql sql-server database relationship

我应该在从数据库中删除某个项目时执行逻辑删除。

我在每个需要执行逻辑删除的表中添加了一个DateTime列。因此,删除时只需更新字段......

UPDATE Client 
SET deleted = GETDATE() 
WHERE Client.CID = @cid

稍后如果应该恢复那么......

UPDATE Client 
SET deleted = NULL 
WHERE Client.CID = @cid

因此典型的选择陈述看起来像......

SELECT * 
FROM client 
WHERE CID = @cid AND deleted IS NULL

但问题是如何在这种方法中处理依赖关系以维护数据库的一致性。对于前者在删除(实际更新)员工之前,我必须进行多项检查,以查看相关表格中是否存在与被删除员工相关的相关出勤/银行账户/工资数据/历史等。

那么做这些事情的正常做法是什么?我是否需要检查

中的所有内容
IF EXISTS (SELECT...)

语句?

修改

如果我想在有相关记录时阻止更新,我可以使用UNION ...

做这样的事情
IF NOT EXISTS (SELECT emp_id FROM BankAccount WHERE emp_id = '100' UNION SELECT EID FROM Attendance WHERE EID = '100' UNION SELECT employee_id FROM SalaryTrans WHERE employee_id = '100')
UPDATE Employee SET Employee.deleted = GETDATE() WHERE emp_id = '100'

这是否可以接受?

2 个答案:

答案 0 :(得分:1)

  

但问题是如何处理依赖关系来维护   这种方法中数据库的一致性。对于前者在删除之前   (实际更新)一个员工,我必须做几个检查,如to   看是否有相关的出勤/银行账户/工资   与员工有关的相关表格中的数据/历史等   删除。

     

那么做这些事情的正常做法是什么?

完全取决于您的申请。

有些公司可能会要求所有待定工资,累计休假日和病假等等,以及#34;处理"在删除某人之前。 处理可能意味着将所有这些内容转换为金钱,这将被添加到最终的薪水中。其他公司可能允许随时删除,因为知道逻辑删除不会影响其他表中的任何相关行。应用程序代码应该知道如何处理将最终检查结果删除给被删除的人。

其他应用程序可能不会处理与工资和税收同等重要的任何事情。他们可能随时允许逻辑删除,而不必担心琐碎的后果。

答案 1 :(得分:1)

查看触发器,它们可能对此有所帮助。

您可以在员工表上定义一个触发器,检查您的逻辑删除是否会导致其他表出现问题。它涉及手动跟踪哪些表需要访问员工,因此它不像允许外键约束为您跟踪那样强大,但它可以工作。我将其设置为“AFTER UPDATE”触发器并回滚事务(在触发器内),如果它找到另一个引用该员工的表。如果他们试图真正删除FK约束中使用的员工,他们会得到回滚,所以没有那么不同。

另一种方法是使用AFTER DELETE触发器将已删除的员工复制到“deleted_employees”表,这样您仍然会依赖它们,但是任何通过FK引用该员工的表都会出错并回滚事务在您的触发器甚至有机会运行之前。

我必须在我的一些东西中使用与你提议的相似的逻辑(只是在每次使用它时检查),并且主要是我在我删除记录时包含我设置的位字段“IsDead”,然后我必须参考每次使用该表。但我主要是构建视图,因为我的模式很复杂,并且在视图的where子句中包含IsDead = 0是微不足道的。我不知道IsDead = 0如何与DelDate IS NULL进行比较,如果你有一个大型数据库,你可能会测试它。