Oracle 12c - 使用另一个表中的值在表中插入值

时间:2014-06-05 22:38:19

标签: sql oracle oracle12c

我有一张表(TABLEA),如此:

type_id  level
1        7
2        4
3        2
4        5

另一张表(TABLEB)如此:

seq_id type_id  name     order level
1      1        display  1     7
2      1        header   2     
3      1        detail   3     
4      2        display  1     4
5      2        header   2     
6      2        detail   3     

TABLEB.TYPE_IDTABLEA.TYPE_ID的FK。目前,我正在手动输入TABLEB数据。

我在TABLEA .. type_id 3和4中有2个新行。

如何使用TABLEB自动填充TABLEA中不存在的数据?我希望自动插入TABLEB中的所有列。

所以,正如你所看到的那样:

  • SEQ_ID将是顺序的
  • ORDER值为1时,NAME值为"显示",LEVEL为7
  • ORDER值为2时,NAME值将为"标题"
  • ORDER值为3时,NAME值将为"详细信息"

我期待插入后:

seq_id type_id  name     order level
1      1        display  1     7
2      1        header   2     
3      1        detail   3     
4      2        display  1     4
5      2        header   2     
6      2        detail   3     
7      3        display  1     2
8      3        header   2     
9      3        detail   3     
10     4        display  1     5
11     4        header   2
12     4        detail   3

感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

你可以:

  1. 让您的应用程序代码填充两个表,即:将适当的记录插入到两个表中。

  2. (听起来像你一直倾向于)让Oracle在幕后工作,即:Oracle在TABLEB中为您执行INSERT。这样做的方法是在TABLEA上创建一个TRIGGER。这是一个可以帮助您入门的示例:https://stackoverflow.com/a/13356277/1680777

  3. 有些人会告诉你TRIGGER可能会使调试变得困难,因为你的部分逻辑在数据库中。批评有一定的有效性。我不会说永远/永远不会使用触发器。在有意义的地方使用它们:它们提供的价值超过了它们的复杂程度。

答案 1 :(得分:0)

所以这可以在纯SQL中完成:INSERT ALL允许我们在同一语句中发出多个插入。

insert all
    into tableb (seq_id, type_id, name, order_id, level_id) 
        values(tableb_id_seq.nextval, type_id, 'display', 1, level_id)
    into tableb (seq_id, type_id, name, order_id) 
        values(tableb_id_seq.nextval+1, type_id, 'header', 2)
    into tableb (seq_id, type_id, name, order_id) 
        values(tableb_id_seq.nextval+2, type_id, 'detail', 3)
select a.type_id, a.level_id from tablea a
minus
select b.type_id, b.level_id from tableb b
/

序列的操作有点滑稽:它是必需的,因为每次调用NEXTVAL都会在一个语句中返回相同的值。显然,为了使这项工作,序列需要增加三:

create sequence tableb_id_seq increment by 3;

这可能足以排除这种方法。作为替代方案,您可以使用(SEQ_ID,ORDER_ID)作为复合主键,但这也不是很好。


顺便说一句,ORDER和LEVEL是关键字:你不能将它们用作列名。