如何使用ID / FK将具有复合PK / FK的表中的数据转储到类似的表中

时间:2018-12-07 18:09:29

标签: sql oracle

说我有一个需要复合PK的表:

Table1
+---------+---------+
|  CompA  |  CompB  |
+---------+---------+
| Value 1 | Value 2 |
| Value 1 | Value 3 |
| Value 2 | Value 3 |
+---------+---------+

然后,我建立了第二个表,并希望将表1中的PK用作新表2中的FK。您可以通过两种方式执行此操作。

选项1 -我最初使用的选项是仅使用表1中的组合键作为表2中的FK。

Table 2
+------+---------+---------+
| T2PK |  CompA  |  CompB  |
+------+---------+---------+
| A    | Value 1 | Value 2 |
| B    | Value 1 | Value 3 |
| C    | Value 2 | Value 3 |
| D    | Value 2 | Value 3 |
+------+---------+---------+

选项2 -我现在要转换到的选项是将表1中的PK更改为ID列,并在值对上施加复合UNIQUE约束

Table 1
+----+---------+---------+
| ID |  CompA  |  CompB  |
+----+---------+---------+
|  1 | Value 1 | Value 2 |
|  2 | Value 1 | Value 3 |
|  3 | Value 2 | Value 3 |
+----+---------+---------+

因此,现在,在要使用表1作为FK的任何其他表中,都引用单个ID列(因为现在是表1的PK)

Table 2
+----+------+
| PK | T1FK |
+----+------+
| A  |    1 |
| B  |    2 |
| C  |    3 |
| D  |    3 |
+----+------+

问题-我最初使用选项1构建表。具有跨越1个实体的多个列的FK变得很烦人,并且使我的join语句比需要的复杂。我现在想过渡到选项2。我已经用选项2的方法构建了表,但是我想不出一种将选项1表的数据转储到新选项2表中的好方法。我无法弄清楚如何将Table1, Option1的数据转储到Table1 Option2的表中并生成ID后,如何将这些生成的ID绑定到同一组Table2 Option1的数据中到新的Table2 Option2

2 个答案:

答案 0 :(得分:1)

假设我们有这些“旧”表:

CREATE TABLE Table1(
  CompA varchar2(10), CompB  varchar2(10), constraint Table1_pk primary key(CompA,CompB)
);

Insert all
into Table1 values('Value 1', 'Value 2')
into Table1 values('Value 1', 'Value 3')
into Table1 values('Value 2', 'Value 3')
SELECT null FROM dual;

CREATE TABLE Table2(
  T2PK varchar2(1),
  CompA varchar2(10), CompB  varchar2(10), 
  constraint Table2_fk foreign key(CompA,CompB) references table1(CompA,CompB)
);

Insert all
into Table2 values('A', 'Value 1', 'Value 2')
into Table2 values('B', 'Value 1', 'Value 3')
into Table2 values('C', 'Value 2', 'Value 3')
into Table2 values('D', 'Value 2', 'Value 3')
SELECT null FROM dual;

我们可以使用以下代码迁移到“新”表:

CREATE TABLE new_Table1(
   ID int PRIMARY KEY,
   CompA varchar2(10), CompB  varchar2(10), 
   constraint new_Table1_uq unique(CompA,CompB)
);

INSERT INTO new_Table1( id, CompA, CompB)
SELECT rownum, CompA, CompB FROM Table1;

CREATE TABLE new_Table2(
   PK  varchar2(1),
   T1FK int,
   constraint new_Table2_fk foreign key(T1FK) references new_Table1( id )
);

INSERT INTO new_Table2( PK , T1FK )
SELECT t2.T2PK, t1.ID
FROM Table2 t2
JOIN new_Table1 t1 
ON t2.CompA = t1.CompA AND t2.CompB = t1.CompB;

这是一个有效的演示:https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=32e852ab929c9431cce31495745ec6ba

答案 1 :(得分:0)

好吧,您可以使用row_number()或rownum分配ID:

create table new_table1 as
    select rownum as table1_id, compA, compB
    from table1;

然后您可以将其用作:

create table new_table2 as
    select t2.id, t2.table1_id
    from table2 t2 left join  -- outer join just in case you have NULL values
         new_table1 t1
         on t2.compA = t1.compA and t2.compB = t1.compB;