甲骨文通过选择从多个表中插入其中一个表可能不具有排(Oracle Insert via Select

2019-07-03 10:32发布

我有一些包含代码和一个长ID的说明代码值表。

我现在要创建引用了一些代码的帐户类型的条目,所以我有这样的事情:

insert into account_type_standard (account_type_Standard_id,
tax_status_id, recipient_id)
( select account_type_standard_seq.nextval,
ts.tax_status_id, r.recipient_id
from tax_status ts, recipient r
where ts.tax_status_code = ?
and r.recipient_code = ?)

如果找到匹配为各自的代码本检索来自tax_status和收件人表中的适当的值。 不幸的是,recipient_code是空的,因此? 替换值可能是零。 当然,隐式连接不返回行,所以一排没有得到插进我的表。

我一直在使用NVL试过吗? 并在r.recipient_id。

我试图迫使外连接的r.recipient_code =? 通过添加(+),但它不是一个明确的加盟,让甲骨文依然没有添加其他行。

任何人都知道的这样的一种方式?

我可以明显地修改语句,以便我做recipient_id的查找外,并有? 而不是r.recipient_id,不从收件人表中所有的选择,但我更喜欢做这一切在1个SQL语句。

Answer 1:

Outter加入在这种情况下“预期”不工作,因为你已经明确告诉你的Oracle只需要的数据,如果该表是标准匹配。 在这种情况下,outter联接变得毫无用处。

一个变通办法

INSERT INTO account_type_standard 
  (account_type_Standard_id, tax_status_id, recipient_id) 
VALUES( 
  (SELECT account_type_standard_seq.nextval FROM DUAL),
  (SELECT tax_status_id FROM tax_status WHERE tax_status_code = ?), 
  (SELECT recipient_id FROM recipient WHERE recipient_code = ?)
)

[编辑]如果期望从一个子选择多个行,则可以添加ROWNUM = 1到每个WHERE子句或使用聚合如MAX或MIN。 当然,这可能不是所有情况下的最佳解决方案。

[编辑]根据注释,

  (SELECT account_type_standard_seq.nextval FROM DUAL),

可以只是

  account_type_standard_seq.nextval,


Answer 2:

Oglester的解决方案的略微简化版本(序列不需要从DUAL一个选择:

INSERT INTO account_type_standard   
  (account_type_Standard_id, tax_status_id, recipient_id) 
VALUES(   
  account_type_standard_seq.nextval,
  (SELECT tax_status_id FROM tax_status WHERE tax_status_code = ?),
  (SELECT recipient_id FROM recipient WHERE recipient_code = ?)
)


Answer 3:

如果ts.tax_status_code是主或备用键或不是,它是不是在这个问题我清楚。 与recipient_code同样的事情。 这将是了解的。

你可以处理你的绑定变量被空的使用OR如下的可能性。 你会同样的事情结合到前两个绑定变量。

如果你关心性能,你会更好地检查,如果你打算绑定值是空或不是,然后发出不同的SQL语句,以避免或。

insert into account_type_standard 
(account_type_Standard_id, tax_status_id, recipient_id)
(
select 
   account_type_standard_seq.nextval,
   ts.tax_status_id, 
   r.recipient_id
from tax_status ts, recipient r
where (ts.tax_status_code = ? OR (ts.tax_status_code IS NULL and ? IS NULL))
and (r.recipient_code = ? OR (r.recipient_code IS NULL and ? IS NULL))


Answer 4:

尝试:

insert into account_type_standard (account_type_Standard_id, tax_status_id, recipient_id)
select account_type_standard_seq.nextval,
       ts.tax_status_id, 
       ( select r.recipient_id
         from recipient r
         where r.recipient_code = ?
       )
from tax_status ts
where ts.tax_status_code = ?


Answer 5:

insert into account_type_standard (account_type_Standard_id, tax_status_id, recipient_id)
select account_type_standard_seq.nextval,
   ts.tax_status_id, 
   ( select r.recipient_id
     from recipient r
     where r.recipient_code = ?
   )
from tax_status ts
where ts.tax_status_code = ?


Answer 6:

insert into received_messages(id, content, status)
    values (RECEIVED_MESSAGES_SEQ.NEXT_VAL, empty_blob(), '');


文章来源: Oracle Insert via Select from multiple tables where one table may not have a row