Oracle Insert via从多个表中选择,其中一个表可能没有行

时间:2008-09-25 02:27:12

标签: sql oracle select insert

我有许多代码值表,其中包含代码和带有Long 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表中检索相应的值。不幸的是,recipient_code是可以为空的,因此?替换值可以为null。当然,隐式连接不会返回一行,因此一行不会插入到我的表中。

我尝试过使用NVL吗?并在r.recipient_id上。

我试图在r.recipient_code =上强制进行外连接?通过添加(+),但它不是显式连接,因此Oracle仍然没有添加另一行。

任何人都知道这样做的方法吗?

我显然可以修改语句,以便在外部查找recipient_id,并且有一个?而不是r.recipient_id,并且根本不从收件人表中选择,但我更愿意在1个SQL语句中完成所有这些。

6 个答案:

答案 0 :(得分:23)

在这种情况下,Outter联接“按预期”不起作用,因为您明确告诉Oracle,如果该表上的条件匹配,您只需要数据。在那种情况下,外部联接变得无用。

解决方法

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 = ?)
)

[编辑] 如果您希望子选择中有多行,则可以为每个where子句添加ROWNUM = 1或使用MAX或MIN等聚合。这当然可能不是所有案例的最佳解决方案。

[编辑]每条评论,

  (SELECT account_type_standard_seq.nextval FROM DUAL),

可以只是

  account_type_standard_seq.nextval,

答案 1 :(得分:7)

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 = ?)
)

答案 2 :(得分:3)

在问题中我不清楚ts.tax_status_code是否是主键或备用键。与recipient_code相同。知道这将是有用的。

您可以使用OR处理绑定变量为null的可能性,如下所示。您可以将相同的东西绑定到前两个绑定变量。

如果您担心性能,最好检查要绑定的值是否为null,然后发出不同的SQL语句以避免OR。

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))

答案 3 :(得分:3)

尝试:

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 = ?

答案 4 :(得分:1)

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 = ?

答案 5 :(得分:-2)

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