Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 在Oracle数据库的两个表中交换外键_Database_Oracle_Foreign Keys - Fatal编程技术网

Database 在Oracle数据库的两个表中交换外键

Database 在Oracle数据库的两个表中交换外键,database,oracle,foreign-keys,Database,Oracle,Foreign Keys,我在Oracle中有两个表,表A和表B都有大约20000到30000条记录 表_B中的记录通过外键链接到表_A中的记录- (表_B包含表_A的主键) 我需要交换外键。i、 e 我希望现在表A应该包含表B的主键。 (这是一项功能性要求-由于前端进行了一些验证,因此无法以当前的数据库实现形式对这些表进行更新。) 此外,在执行此操作时,我希望从(TABLE_B->TABLE_A)链接的记录仍然保持链接状态。 现在通过新外键(TABLE_A->TABLE_B) 外键可以很容易地移动,通过两个ALTERT

我在Oracle中有两个表,表A和表B都有大约20000到30000条记录

表_B中的记录通过外键链接到表_A中的记录- (表_B包含表_A的主键)

我需要交换外键。i、 e

我希望现在表A应该包含表B的主键。 (这是一项功能性要求-由于前端进行了一些验证,因此无法以当前的数据库实现形式对这些表进行更新。)

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

外键可以很容易地移动,通过两个ALTERTABLE命令,主要的问题是保持数据并正确地重新链接它

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


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

假设以下结构:

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记录,这应该只需要很少的时间


上面缺少的唯一一点是删除表B上的旧主键约束,并在表A上添加新的主键约束(B_id)。

除非这些表是1:1的关系,即表A中的每一行在表B中有一行,表B中的每一行在表A中有一行,否则我看不出这是可行的。如果它们是1:1,我不明白为什么它们是两个表而不是一个。@davidadridge,1:1关系在超类/子类模型中很常见。避免在一个宽表中出现大量空列。@JeffreyKemp是的,我想是的——但从引用子类表的超类开始将是一个相当大的错误。是的,很难想象模型会以这种方式混乱。谢谢你的回答,它工作得很好。我想指出的一点是,不需要您提到的最后一步,因为我们仍然需要b_id作为表b的主键。对于表a,主键仍然是a_id。此外,在MERGE语句的语法中,缺少USING关键字。我建议在您的回答中对此进行编辑。