2015-04-07 55 views
1

我在Oracle TABLE_A和TABLE_B的两个表中都有大约20000到30000条记录。在Oracle数据库的两个表中交换外键

在表-B的记录是通过外键链接到TABLE_A记录 - (表-B包含TABLE_A的主键)

我需要交换的外键。即

我希望现在TABLE_A应该包含TABLE_B的主键。 (这是一个功能要求 - 因为在前端的一些验证,在当前形式的数据库实现这些表上的更新是不可能的。)

此外,虽然这样做,我想记录从(TABLE_B - > TABLE_A)链接仍保持链接。 现在通过新的外键(TABLE_A - > TABLE_B)。

FOREIGN KEY可以通过几个ALTER TABLE命令轻松移动,主要问题区域是保持数据并正确地重新链接它。

执行此操作最明显的方法将涉及到备份整个表,然后创建新脚本以在两个表中重新插入更新的数据。

有没有更快的方法来做到这一点,没有任何错误的机会。

+1

除非表格处于1:1关系 - 即。表A中的每一行在表B中都有一行,表B中的每一行在表A中都有一行 - 我没有看到这个工作。如果他们是1:1,我不明白他们为什么是两张桌子,而不是一张桌子。 –

+0

@DavidAldridge,1:1关系在超类/子类模型中很常见。在单个宽表中避免大量NULL列。 –

+0

@JeffreyKemp是的,我想是的 - 尽管引用子类表的超类开始会是相当错误的。 –

回答

1

假设以下结构:

TABLE_A (a_id [pk], ...) 
TABLE_B (b_id [pk], a_id, ...) 
    unique constraint on TABLE_B (a_id) 
    referential constraint TABLE_B (a_id) -> TABLE_A (a_id) 

你可以做这样的事情,假设你的系统可以处理暂时故障:

ALTER TABLE TABLE_A ADD (b_id NUMBER); 

MERGE INTO TABLE_A t USING 
    (SELECT b_id, a_id FROM TABLE_B) s 
ON (t.a_id = s.a_id) 
WHEN MATCHED THEN UPDATE 
    SET t.b_id = s.b_id; 

ALTER TABLE TABLE_A ADD CONSTRAINT a_b_fk 
    FOREIGN KEY (b_id) REFERENCES TABLE_B (b_id); 

ALTER TABLE TABLE_B DROP COLUMN a_id; 

因为只有30K的记录应该采取很少的时间。

上述缺失的唯一缺点是删除TABLE_B上的旧主键约束并在TABLE_A(b_id)上添加新的主键约束。

+0

感谢您的回答,它工作正常。只是我想指出的一点是,您提到的最后一步不会被要求,因为我们仍然需要b_id作为TABLE_B的主键。对于TABLE_A,主键仍然是a_id。 另外,在MERGE语句的语法中,USING关键字缺失我已经建议在您的答案中对其进行编辑。 – sumit

+0

非常感谢您的支持。 –