A Oracle Inserir via Select de várias tabelas onde uma tabela não podem ter uma linha

StackOverflow https://stackoverflow.com/questions/131164

  •  02-07-2019
  •  | 
  •  

Pergunta

Eu tenho um número de tabelas de valores de código que contêm um código e uma descrição com uma id longa.

Agora eu quero criar uma entrada para um tipo de conta que faz referência a um número de códigos, então eu tenho algo parecido com isto:

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

Este recupera os valores apropriados das tabelas tax_status e receptores, se for encontrada uma correspondência para os respectivos códigos. Infelizmente, recipient_code é anulável, e, portanto, a? valor de substituição pode ser nulo. Claro, o implícito junção não retornar uma linha, então uma linha não se inserido em minha mesa.

Eu tentei usar NVL no? e na r.recipient_id.

Eu tentei forçar uma junção externa sobre os = r.recipient_code? adicionando (+), mas não é participar de uma explícita, de modo a Oracle ainda não adicionar outra linha.

Alguém sabe de uma maneira de fazer isso?

Eu, obviamente, pode modificar a instrução para que eu fazer a pesquisa do recipient_id externamente, e ter um? em vez de r.recipient_id, e não selecione da tabela de destinatário em tudo, mas eu prefiro fazer tudo isso em declaração 1 SQL.

Foi útil?

Solução

Outter junta não funcionam "como esperado", nesse caso, porque você ter dito explicitamente a Oracle só deseja dados se que os critérios em que os jogos de mesa. Nesse cenário, o outter juntar-se torna-se inútil.

Uma forma de contornar

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

[Edit] Se você espera que várias linhas a partir de uma sub-selecionar, você pode adicionar ROWNUM = 1 para cada cláusula WHERE ou usar um agregado tais como MAX ou MIN. Isto, obviamente, pode não ser a melhor solução para todos os casos.

[Edit] Per comentário,

  (SELECT account_type_standard_seq.nextval FROM DUAL),

pode ser apenas

  account_type_standard_seq.nextval,

Outras dicas

Uma versão ligeiramente simplificada da solução da Oglester (a seqüência não requer uma escolha de 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 = ?)
)

Não estava claro para mim na questão se ts.tax_status_code é uma chave primária ou suplente ou não. A mesma coisa com recipient_code. Isso seria útil para conhecer.

Você pode lidar com a possibilidade de sua variável de ligação sendo nula usando um OR como segue. Você ligaria a mesma coisa para as duas primeiras variáveis ??de ligação.

Se você está preocupado com o desempenho, você seria melhor para verificar se os valores que pretende vincular são nulos ou não e, em seguida, emitir instrução SQL diferente para evitar o 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))

Tente:

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 = ?
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 = ?
insert into received_messages(id, content, status)
    values (RECEIVED_MESSAGES_SEQ.NEXT_VAL, empty_blob(), '');
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top