13

コードと長い 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 可能であるため、? 置換値は null の可能性があります。もちろん、暗黙的な結合は行を返さないため、行はテーブルに挿入されません。

でNVLを使用してみましたか?およびr.recipient_idで。

r.recipient_code = ? で外部結合を強制しようとしました。(+) を追加しますが、これは明示的な結合ではないため、Oracle はまだ別の行を追加しませんでした。

これを行う方法を知っている人はいますか?

外部で recipient_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

試す:

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 に答える
3

ts.tax_status_code が主キーまたは代替キーであるかどうかは、質問では明確ではありませんでした。受信者コードと同じです。これは知っておくと便利です。

次のように OR を使用して、バインド変数が null になる可能性に対処できます。同じものを最初の 2 つのバインド変数にバインドします。

パフォーマンスが気になる場合は、バインドする値が 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 に答える
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 に答える