Oracle über Wählen Sie aus mehreren Tabellen einfügen, wo eine Tabelle keine Zeile haben kann

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

  •  02-07-2019
  •  | 
  •  

Frage

Ich habe eine Reihe von Codewert-Tabellen, die einen Code und eine Beschreibung mit einer Lange-ID enthalten.

Ich möchte nun einen Eintrag für einen Account erstellen, die eine Anzahl von Codes verweist, so habe ich so etwas wie folgt aus:

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

Dies ruft die entsprechenden Werte aus den tax_status und Empfängertabellen, wenn eine Übereinstimmung für ihre jeweiligen Codes gefunden wird. Leider recipient_code ist nullable und damit das? Substitutionswert könnte null sein. Natürlich ist die implizite Join ist eine Zeile nicht zurück, so eine Zeile nicht in meine Tabelle eingefügt bekommt.

Ich habe versucht NVL mit auf das? und auf der r.recipient_id.

Ich habe versucht, eine äußere Kraft kommen auf dem r.recipient_code =? durch Zugabe von (+), aber es ist kein explizites beitreten, so Oracle immer noch nicht eine weitere Zeile hinzufügen.

Wer weiß einen Weg, dies zu tun?

Ich kann natürlich die Aussage ändern, so dass ich die Suche nach dem recipient_id extern tun, und ein Produkt? statt r.recipient_id, und wählen Sie nicht aus der Empfängertabelle überhaupt, aber ich würde es vorziehen, all dies in 1 SQL-Anweisung zu tun.

War es hilfreich?

Lösung

Outter verbindet nicht funktionieren „wie erwartet“ in diesem Fall, weil Sie explizit Oracle gesagt haben Sie nur Daten wollen, wenn die Kriterien für diese Tabelle übereinstimmt. In diesem Szenario join der äußer ist unbrauchbar gemacht.

Eine Behelfslösung

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

[Bearbeiten] Wenn Sie mehrere Zeilen aus einer Unterauswahl erwarten, können Sie ROWNUM = 1 zu jeder where-Klausel hinzuzufügen oder ein Aggregat wie MAX oder MIN verwenden. Dies kann natürlich nicht die beste Lösung für alle Fälle sein.

[Bearbeiten] Per Kommentar,

  (SELECT account_type_standard_seq.nextval FROM DUAL),

kann nur

  account_type_standard_seq.nextval,

Andere Tipps

Eine etwas vereinfachte Version von Oglester-Lösung (die Sequenz benötigt keine wählen Sie aus 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 = ?)
)

Es war ich in der Frage nicht klar, ob ts.tax_status_code ein primärer oder alternativer Schlüssel ist oder nicht. Das Gleiche gilt für recipient_code. Dies wäre nützlich zu wissen.

Sie können mit der Möglichkeit, Ihre bind Variable, null behandeln eine ODER wie folgt verwendet wird. Sie würden das Gleiche zu den ersten beiden Bindungsvariablen binden.

Wenn Sie sich Sorgen über die Leistung sind, würden Sie besser sein, zu überprüfen, ob die Werte, die Sie zu binden beabsichtigen, sind null oder nicht, und dann verschiedene SQL-Anweisung geben Sie den OR zu vermeiden.

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

Versuchen:

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(), '');
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top