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

Posted

技术标签:

【中文标题】Oracle 12c - 使用另一个表中的值在表中插入值【英文标题】:Oracle 12c - Insert values in a table using values from another table 【发布时间】:2014-06-05 22:38:18 【问题描述】:

我有一张像这样的桌子 (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.. 中有 2 个新行。type_id 3 和 4。

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

所以,如你所见:

SEQ_ID 将是连续的 当ORDER值为1时,NAME值为“显示”,LEVEL为7 当ORDER值为2时,NAME值为“header” 当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

感谢任何帮助!

【问题讨论】:

【参考方案1】:

您可以:

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

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

有些人会告诉您,TRIGGER 可能会使调试变得困难,因为您的部分逻辑在数据库中。这种批评是有道理的。我不会说总是/从不使用触发器。在有意义的地方使用它们:它们提供的价值超过了它们的复杂性。

【讨论】:

【参考方案2】:

所以这可以在纯 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 是关键字:您不能将它们用作列名。

【讨论】:

以上是关于Oracle 12c - 使用另一个表中的值在表中插入值的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 12c - 使用表中的值构建选择语句

查询输出表中不存在的值

Oracle 12c - 根据不同表中的值动态生成 where 子句

无法使用 Liquibase 中的序列在表中插入值

用另一个表中的值更新一个表

Oracle 删除表中的重复行并使用另一个表中的值更新行