Подтвердить что ты не робот

Oracle Insert via Выбрать из нескольких таблиц, где одна таблица может не содержать строку

У меня есть несколько таблиц значений кода, которые содержат код и описание с длинным идентификатором.

Теперь я хочу создать запись для типа учетной записи, которая ссылается на количество кодов, поэтому у меня есть что-то вроде этого:

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 имеет значение NULL, и поэтому? значение замены может быть нулевым. Конечно, неявное объединение не возвращает строку, поэтому строка не вставлена ​​в мою таблицу.

Я пробовал использовать NVL? и на r.recipient_id.

Я пытался заставить внешнее соединение на r.recipient_code =? добавив (+), но это не явное соединение, поэтому Oracle по-прежнему не добавляло еще одну строку.

Кто-нибудь знает, как это сделать?

Я могу, очевидно, изменить инструкцию так, чтобы я искал внешний вид получателя извне и имел? вместо r.recipient_id, и вообще не выбирайте из таблицы получателей, но я бы предпочел сделать все это в 1 инструкции SQL.

4b9b3361

Ответ 1

Соединения 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 = ?)
)

[Изменить] Если вы ожидаете несколько строк из подвыборки, вы можете добавить ROWNUM = 1 в каждое предложение where ИЛИ использовать агрегат, такой как MAX или MIN. Это, конечно, может быть не лучшим решением для всех случаев.

[Изменить] За комментарий

  (SELECT account_type_standard_seq.nextval FROM DUAL),

может быть просто

  account_type_standard_seq.nextval,

Ответ 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 = ?)
)

Ответ 3

Мне не было ясно в вопросе, является ли ts.tax_status_code основным или альтернативным ключом или нет. То же самое с recipient_code. Это было бы полезно знать.

Вы можете иметь дело с возможностью того, что ваша переменная связывания равна null, используя OR следующим образом. Вы бы связали одно и то же с первыми двумя переменными связывания.

Если вы обеспокоены производительностью, вам лучше проверить, являются ли значения, которые вы намереваетесь привязать, являются нулевыми или нет, а затем выдаете другую инструкцию 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))

Ответ 4

Try:

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

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

Ответ 6

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