13

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

我试过在 ? 在 r.recipient_id 上。

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

有人知道这样做的方法吗?

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

4

6 回答 6

24

在这种情况下,外部联接不会“按预期”工作,因为您已明确告诉 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 = ?)
)

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

[编辑] 根据评论,

  (SELECT account_type_standard_seq.nextval FROM DUAL),

可以只是

  account_type_standard_seq.nextval,
于 2008-09-25T02:35:51.467 回答
8

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 = ?)
)
于 2008-09-26T10:42:40.833 回答
3

我不清楚 ts.tax_status_code 是主键还是备用键。与收件人代码相同。知道这将很有用。

您可以使用 OR 来处理绑定变量为 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))
于 2008-09-25T05:05:08.860 回答
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 = ?
于 2008-09-25T11:22:15.833 回答
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 = ?
于 2012-11-28T09:00:30.577 回答
-2
insert into received_messages(id, content, status)
    values (RECEIVED_MESSAGES_SEQ.NEXT_VAL, empty_blob(), '');
于 2010-05-20T08:38:50.083 回答