用于在不同模式的表之间拆分行的迁移脚本

时间:2011-11-01 11:00:19

标签: sql oracle data-migration

我有一个包含以下列的表,我试图按如下方式拆分它。如何为Oracle中的以下转换编写迁移脚本

源:

create table abc (id pk, col1, col2, col3, col4, col5, col6)

目标:

create table def (id pk, col1, col2)
create table ghi (id pk, def_id fk, value)

鉴于这个起点......

insert into table abc values (1, 1, 2, 3, 4, 5, 6)
insert into table abc values (2, 7, 8, 9, 10, 11, 12)

...数据的翻译后映射如下

def contains (1, 1, 2)
ghi contains (1, 1, 3)
ghi contains (2, 1, 4)
ghi contains (3, 1, 5)
ghi contains (4, 1, 6)

def contains (2, 7, 8)
ghi contains (5, 2, 9)
ghi contains (6, 2, 10)
ghi contains (7, 2, 11)
ghi contains (8, 2, 12)

最重要的限制是,只有当ghi中的相应列值为abc

时才会在not null中生成行

1 个答案:

答案 0 :(得分:1)

我认为最简单的方法是从源表中选择两个。第一个是cinch:

insert into def
select id, col1, col2 from abc

第二个使用INSERT ALL语法:

INSERT ALL
   WHEN col3 is not null THEN
      INTO ghi values (some_seq.nextval, id, col3)
   WHEN col4 is not null THEN
      INTO ghi values (some_seq.nextval, id, col4)
   WHEN col5 is not null THEN
      INTO ghi values (some_seq.nextval, id, col5)
   WHEN col6 is not null THEN
      INTO ghi values (some_seq.nextval, id, col6)
   SELECT id, col3, col4, col5, col6
      FROM abc;

注意,我假设序列SOME_SEQ是GHI的主键值的来源。您可能想要一些其他机制。


嗯,运行我的代码我得到了这个结果:

SQL> select * from ghi;

        ID     DEF_ID      VALUE
---------- ---------- ----------
         1          1          3
         2          2          9
         1          1          4
         2          2         10
         1          1          5
         2          2         11
         1          1          6
         2          2         12

8 rows selected.

SQL> 

正如您所看到的,SOME_SEQ仅在ABC 中的两行中增加了 GHI中的八行。这是有道理的,因为在同一语句中对NEXTVAL的两次调用返回相同的值,但我希望每个INSERT都会单独计算。

好吧,好吧。这意味着对于您的迁移,在填充GHI之前,您无法强制执行GHI上的主键。所以

  1. 禁用主键(或创建没有主键的表)。
  2. 使用来自ABC
  3. 的数据填充它
  4. 填充主键列(以任何方式)
  5. 启用主键约束
  6. 或者,您需要找到一些其他方法来填充GHI ID列。