【问题标题】:Swap the foreign key in two tables in Oracle database交换Oracle数据库两张表的外键
【发布时间】:2015-04-07 11:25:28
【问题描述】:

我在 Oracle TABLE_A 和 TABLE_B 中有两个表,这两个表都有大约 20000 到 30000 条记录。

TABLE_B 中的记录通过外键链接到 TABLE_A 中的记录 - (TABLE_B 包含 TABLE_A 的主键)

我需要交换外键。即

我希望现在 TABLE_A 应该包含 TABLE_B 的主键。 (这是一个功能需求——由于前端的一些验证,在当前数据库实现形式中对这些表的更新是不可能的。)

此外,在执行此操作时,我希望从 (TABLE_B -> TABLE_A) 链接的记录仍保持链接状态。 现在通过新的外键 (TABLE_A -> TABLE_B)。

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

最明显的方法是备份整个表,然后创建新脚本以在两个表中重新插入更新的数据。

有没有更快的方法来做到这一点而不会出错。

【问题讨论】:

  • 除非表格是 1:1 的关系——即。表 A 中的每一行在表 B 中都有一行,表 B 中的每一行在表 A 中都有一行——我认为这不起作用。如果它们是 1:1,我不明白为什么它们是两张桌子而不是一张。
  • @DavidAldridge,1:1 关系在超类/子类模型中很常见。避免在单个宽表中出现大量 NULL 列。
  • @JeffreyKemp 是的,我想是的——不过,从引用子类表的超类开始是相当错误的。
  • 是的,很难想象模型怎么会被这样弄得一团糟。

标签: database oracle foreign-keys


【解决方案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) 上添加新主键约束。

【讨论】:

  • 感谢您的回答,它工作正常。我想指出的一点是您提到的最后一步,因为我们仍然需要 b_id 作为TABLE_B 的主键。对于 TABLE_A,主键仍然是 a_id。此外,在 MERGE 语句的语法中,缺少 USING 关键字我建议在您的答案中对此进行编辑。
猜你喜欢
  • 1970-01-01
  • 2016-08-19
  • 2021-03-15
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
相关资源
最近更新 更多