如何删除具有双向依赖关系的行?
我正在使用 Oracle 10g Express 并尝试从具有双向约束的表中删除记录。我正在尝试取消通过 Hibernate 生成的数百个表和依赖项的线程(此时无法更改),但这是一个极其简化的示例:
create table TableA (id number(19,0) not null, ..., rTableA_id number(19,0), primary key (id));
create table TableB (id number(19,0) not null, ..., rTableB_id number(19,0), primary key (id));
alter table TableA add constraint FKA1 foreign key (rTableA_id) references TableB;
alter table TableB add constraint FKB1 foreign key (rTableB_id) references TableA;
尝试从任一表中删除条目返回以下内容:
编辑:在我的情况下,外键前缀为 SYS_
ORA-02292: integrity constraint (XXX.FKA1) violated - child record found
我也尝试禁用约束,但所有尝试都是徒劳的:
ORA-02297: cannot disable constraint (XXX.FKA1) - dependencies exist
I'm using Oracle 10g Express and trying to delete records from tables with bi-directional constraints. I'm trying to un-thread hundreds of tables and dependencies generated via Hibernate (which can't be changed at this point), but here is an extremely simplified example:
create table TableA (id number(19,0) not null, ..., rTableA_id number(19,0), primary key (id));
create table TableB (id number(19,0) not null, ..., rTableB_id number(19,0), primary key (id));
alter table TableA add constraint FKA1 foreign key (rTableA_id) references TableB;
alter table TableB add constraint FKB1 foreign key (rTableB_id) references TableA;
Trying to delete entries from either table returns the following:
EDIT: This happens in my case with foreign keys prefixed with SYS_
ORA-02292: integrity constraint (XXX.FKA1) violated - child record found
I've also tried to disable constraints but all attempts are futile:
ORA-02297: cannot disable constraint (XXX.FKA1) - dependencies exist
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想知道你的数据首先是如何进入这种状态的,因为你的外键
not null
。如果两个表一开始都是空的,那么您将永远无法在任一表中插入行。暂时忽略这一点,重新创建您的场景,禁用约束没有问题:
结果:
我不确定在尝试禁用外键时如何收到
ORA-02297
错误。当禁用外键依赖的主键或唯一键时,通常会出现该错误。我怀疑您真正想做的是将约束设置为
最初推迟
。这将允许您单独对每个表执行插入和删除,只要在提交事务之前更新或删除相应的行即可:结果:
I have to wonder how your data got in this state in the first place, since your foreign keys are
not null
. If both tables were empty to start with, you'd never be able to insert a row into either table.Ignoring that for a moment, recreating your scenario, I have no problem disabling the constraints:
Result:
I'm not sure how you'd get a
ORA-02297
error when attempting to disable a foreign key. That error is typically seen when disabling a primary or unique key that a foreign key relies upon.I suspect what you really want to do is set the constraints to
initially deferred
. This would allow you to perform inserts and deletes to each table individually, as long as the corresponding row was updated or deleted before the transaction is commited:Result:
您确定 Hibernate 不能被告知将约束创建为可延迟的吗?如果 DDL 不使用 DEFERRABLE 关键字,则默认情况下约束将是不可延迟的。这意味着您将无法删除数据。如果您有一个带有循环引用的模式,您总是希望将外键约束声明为可延迟的。
您可以删除约束,删除数据,然后重新创建约束(使用 Hibernate 的 DDL 或在末尾添加 INITIALLY DEFERRED DEFERRABLE 子句)。但是,如果您以任何频率从任一表中删除数据,这将是一个很大的痛苦。如果新 A 行想要引用您正在创建的新 B 行,那么您在插入新数据时也可能会遇到问题。
Are you sure that Hibernate cannot be told to create the constraints as deferrable? If the DDL doesn't use the
DEFERRABLE
keyword, the constraints will be non-deferrable by default. That is going to mean that you won't be able to delete the data. If you have a schema with circular references, you would always want to declare your foreign key constraints to be deferrable.You could drop the constraints, delete the data, and then re-create the constraints (either using Hibernate's DDL or by adding the
INITIALLY DEFERRED DEFERRABLE
clause at the end). But that would be a major pain if you delete data from either table with any sort of frequency. You'll also tend to have problems inserting new data if the new A row wants to reference the new B row you're creating.我无法添加
INITIALLY DEFERRED
,因为数据库(以及底层 Hibernate 脚本)已经存在。对于新系统,这本来是一个选项,但是,有许多工具(我只知道其中几个)依赖于当前形式的数据库,并且我太担心将此参数添加到700桌。因此,我使用了以下解决方案:
I was unable to add
INITIALLY DEFERRED
because the databases (as well as the underlying Hibernate scripts) already exist. For new systems, this would have been an option, however, there are many tools (of which I only know several) which rely on the Database in its current form and I was too afraid of any unintended side-effects by adding this parameter to 700 tables.Therefore, I used the following solution: