Sql 使用Oracle将树从一个表插入到另一个表的最佳方法是什么

Sql 使用Oracle将树从一个表插入到另一个表的最佳方法是什么,sql,plsql,insert,hierarchy,Sql,Plsql,Insert,Hierarchy,我有一张放树的桌子。有一个节点id和父节点id 当我尝试以下方法时: insert into table1 select * from table2 start with node_id = 1 connect by prior node_id = parent_id order by parent_id nulls first 我得到这个错误: Error starting at line 6 in command: insert into table1 select * from tabl

我有一张放树的桌子。有一个节点id和父节点id

当我尝试以下方法时:

insert into table1 select * from table2 start with node_id = 1 connect by prior node_id = parent_id order by parent_id nulls first
我得到这个错误:

Error starting at line 6 in command:
insert into table1 select * from table2 start with node_id = 1 connect by prior node_id = parent_id order by parent_id nulls first
Error report:
SQL Error: ORA-02291: integrity constraint (XVTEST.REGIONAL_DEFAULT_DELETE) violated - parent key not found
02291. 00000 - "integrity constraint (%s.%s) violated - parent key not found"
*Cause:    A foreign key value has no matching primary key value.
*Action:   Delete the foreign key or add a matching primary key.

我明白为什么我会犯这个错误。我只是想知道是否有一种方法可以在不进行递归pl/sql过程的情况下实现这一点。思想?如果不可能,是否有人有这样一个过程,我可以将其用作示例?

一个选项是将外键约束创建为可延迟的,然后为事务将其设置为延迟,这样外键约束的实施将延迟到提交

请注意,当表的内容违反约束时,您不希望执行任何SELECT。在某些情况下,某些SELECT语句将返回意外或不一致的结果。(一定要考虑触发器执行的select语句)



一些有用的参考资料:


增编:

这种方法特别适用于Oracle数据库,可能不适用于其他关系数据库引擎

当约束被延迟时,禁止对表执行选择的警告仅适用于延迟约束的会话。其他会话将看到一致状态,因为它们不会看到任何未提交的更改


使用延迟约束优于禁用和重新启用约束,因为禁用约束会影响所有会话,而重新验证约束会消耗大量资源(对于大型表)。

我甚至没有听说过延迟约束……谢谢!这正是我需要的!
-- to create foreign key constraints as deferrable
ALTER TABLE my_table ADD CONSTRAINT my_table_fk1 
FOREIGN KEY (other_table_id) REFERENCES other_table (id)
DEFERRABLE INITIALLY IMMEDIATE;

-- defer all deferrable constraints until the next commit
ALTER SESSION SET CONSTRAINTS=DEFERRED;
-- or
SET CONSTRAINTS ALL DEFERRED;

-- dml operations may now temporarily violate constraints
INSERT ... ; 
UPDATE ... ;

-- you can check the constraints before the commit
SET CONSTRAINTS ALL IMMEDIATE;

-- all deferred constraints will be enforced at the next commit
-- (a fk violation exception will be raised here, rather than by the DML)
COMMIT;