Oracle多行'插入(如果不存在)' from select with table literal

时间:2017-03-14 12:47:30

标签: sql oracle insert multirow

假设我有以下表结构:

a (a_id number primary key, a_code varchar unique not null)
b (b_id number primary key, a_id number foreign key references a(a_id), b_value varchar

我需要在表b上插入几百对(a_id, b_value)(如果它们尚不存在),并且我的信息是(a_code, b_value)。我来自Postgres的背景,这样做很简单,但我很难找到一种方法在Oracle中将其拉出来而不需要创建并随后删除物化视图,或者每次执行一次插入操作行。

这是我能够提出的最难看的解决方案:

insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(b_value, iun_b_value) */
into b (b_id, a_id, b_value)
select b_id.nextval, a_id, b_value
from a
inner join

(select 'code1' a_code, 'value1' b_value from dual union all
select 'code2' a_code, 'value2' b_value from dual union all
select 'code3' a_code, 'value3' b_value from dual union all
select 'code4' a_code, 'value4' b_value from dual) new

on a.a_code = new.b_value

但有人告诉我,我无法使用该语义提示来处理生产中的重复行,所以我尝试了这个:

merge into b using
  (select a_id, b_value
  from a inner join 

  (select 'code1' a_code, 'value1' b_value from dual union all
  select 'code2' a_code, 'value2' b_value from dual union all
  select 'code3' a_code, 'value3' b_value from dual union all
  select 'code4' a_code, 'value4' b_value from dual) new

  new on a.a_code = new.a_code) insert_codes

on (insert_codes.a_code = b.a_code and insert_codes.b_value = b.b_value)
when not matched then
  insert (b.b_id, b.a_id, b.b_value)
  values (b_id.nextval, insert_codes.a_id, 1, insert_codes.b_value)

但是当我在尝试使用"ORA-00980: synonym translation is no longer valid"子句解决此问题时在子选择中引用别名时,我得到了同样的where not exists错误。

如果没有实体化视图或多次插入,有没有办法做到这一点?

1 个答案:

答案 0 :(得分:0)

看着我的简化例子让我意识到错误。 on子句是

on (insert_codes.a_code = b.a_code and insert_codes.b_value = b.b_value)

但它应该是

on (insert_codes.a_id = b.a_id and insert_codes.b_value = b.b_value)

这样可行:

merge into b using
  (select a_id, b_value
  from a inner join 

  (select 'code1' a_code, 'value1' b_value from dual union all
  select 'code2' a_code, 'value2' b_value from dual union all
  select 'code3' a_code, 'value3' b_value from dual union all
  select 'code4' a_code, 'value4' b_value from dual) new

  new on a.a_code = new.a_code) insert_codes

on (insert_codes.a_id = b.a_id and insert_codes.b_value = b.b_value)
when not matched then
  insert (b.b_id, b.a_id, b.b_value)
  values (b_id.nextval, insert_codes.a_id, 1, insert_codes.b_value)

在此发布以防其他人在将来无法拔出相同类型的插页时出现。