2012-01-04 83 views
1

每隔一段时间我都必须从我们的数据库中删除用户。用户存储在名为TPM_USER的表中。问题是,有一堆表在TPM_USER.USERID上有外键约束。更糟糕的是,这些限制使用ON CASCADE DELETE。有一天,我删除了一个我认为没有被任何东西使用的用户(这是几个小时前错误创建的重复用户),但它没有任何警告地清除了一堆重要数据。我可以暂时禁用Oracle中的级联删除吗?

就我个人而言,我讨厌级联删除。我认为它们很危险,只有在两个实体确实相互依赖的情况下才能使用。我很想将它们全部移除,但是这种架构相当复杂,而且这个时候可能会变得太大而无法改变。

我的问题:上运行TPM_USER一个DELETE声明之前,我可以让Oracle告诉我到底是什么会因此而被删除?或者,如果任何外键被违反,我是否可以暂时禁用任何级联并获得错误?

谢谢!

+0

我个人认为,*你*的系统中的危险实体。不是'ON CASCADE DELETE'子句;-)我建议编写一个用于删除用户的存储过程,用于检查用户“可能”不应该被删除的相关情况。 – 2012-01-04 21:19:17

+0

或者如果错误,可能会进行处理。如果您需要删除用户,指定一些标志(例如禁用,锁定,...),并在更长的时间周期(也许是几周)后删除。当然,这也会要求应用程序了解这种更改,但是更好的做法是使用删除和从备份恢复;) – rkosegi 2012-01-04 21:23:42

+0

@LukasEder - 哦,我肯定会同意我是危险的组件,特别是玩弄一个我不明白的复杂架构,然后在我破坏事情时公开抱怨。我的问题是我如何保护自己免受级联删除造成的继承危险。 – 2012-01-04 21:34:22

回答

2

在回答你的问题时,我不知道任何简单的方法来显示级联删除语句中将被删除的内容。你可以编写脚本,但它会非常复杂,因为你必须动态地依赖关系树,只显示与删除标准相关的记录。

无论如何,你可以通过使用禁用的约束:

alter table TABLE_NAME disable constraint FK_CONSTRAINT_NAME; 

(使用 '启用' 重新启用它)。

显然你应该知道如果你这样做,而另一个用户从同一个表中删除,那么Oracle将不会执行这个约束,并且可能发生不好的事情。

你可以得到所有的表/约束名称引用TPM_USER.USERID与列表:

select table_name, constraint_name from user_constraints 
    where r_constraint_name in (
    select constraint_name 
    from user_constraints 
    where constraint_type = 'P' 
    and table_name = 'TPM_USER'); 

(使用ALL_CONSTRAINTS如果您有跨架构的依赖)

+0

'select'语句的'+ 1'获得引用表的列表,这将*非常有用!如果没有更具体的内容出现,我会接受这个答案。 – 2012-01-04 22:25:07