![]() |
Datenbank: Oracle • Version: 11 • Zugriff über: verschiedenes
[PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Wenn man einen Datensatz updaten möchte, aber nicht sicher ist, ob er bereits existiert kann man das Kommando "MERGE INTO" nutzen. Welches in einem Abwasch bspw. eine "Select count.."-Abfrage macht und dann entscheidet, ob ein Insert oder ein update notwendig ist.
Ich brauche dies aber des öftern für einen anderen Konstrukt. Ich möchte eine Entscheidung ob ich ein "Select ID ..." oder ein "Insert ... returning ID ..." brauche in einem Befehl (ID ist bei mir immer der PK) Da ich vermute, dass ich damit nicht der einzige bin (ich im Netz aber nichts finde; bei "Select oder Insert" findet man zu viel), würde ich gern mal wissen, ob es dafür etwas gibt. Bisher löse ich das folgendermaßen:
SQL-Code:
Select count(ID) into c from ...
if c=0 then begin insert into dbt_Channel ... returning ID into result; commit; exception when dup_val_on_index then c:=1; -- falls zwischenzeitlich ein zweiter User einen Datensatz eingefügt hat?!? when others then raise; end; end if; if c>0 then Select ID into result ... end if; return(result); |
AW: [PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Ob es bei PLSQL geht, weiß ich nicht, aber die SQL-Syntax kennt da ein "Insert or Update".
Es ist praktisch ein INSERT und falls es Probleme mit doppelten/vorhandenen Keys gibt, dann wird das UPDATE versucht.
SQL-Code:
field1 ist hierbei z.B. ein Primary-/Unique-Key und deshalb hab ich ihn beim Update weggelassen, da er sich ja eh nicht ändert
INSERT INTO `table` ( 'field1', 'field2' ) VALUES ( 'value1', 'value2' )
ON DUPLICATE KEY UPDATE 'field2' = 'value2' und über diesen schon der zu ändernde Datensatz ausgewählt wurde. |
AW: [PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Liefert dir MERGE die ID nicht zuück?
Unter FireBird könnte man
SQL-Code:
verwenden
Update or insert ... matching ... returning ID;
|
AW: [PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Oh Sorry,
ich sehe, ich habe die Frage falsch erklärt. Eine "insert-update" Variante ![]() Schonmal Danke für Eure Bemühungen. Edit: Wobei mir deine Syntax, himi, auch neu ist (schön wenn man mal redet, da lernt man immer was), ich sie aber hier nicht brauche. |
AW: [PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Irgendwie hast du mehr Code als nötig.
SQL-Code:
[/QUOTE]
begin
insert into dbt_Channel ... returning ID into result; commit; return(result); exception when dup_val_on_index then return ID; -- falls zwischenzeitlich ein zweiter User einen Datensatz eingefügt hat?!? when others then raise; end; |
AW: [PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Hi HeZa,
jo, so kann man es auch machen. Es bestehen aber zwei Nachteile: 1. Exception, die man vorher abfangen kann sind doof (und normalerweise auch sehr performanceraubend, zumal in dem Fall bis auf den ersten Eintrag immer die Exception geworfen wird) 2. Da auf das Insert ein Trigger (inkl. sequence) angelegt ist, welcher die ID setzen soll (=AutoInc bei mySQL), läuft der auch hoch, obwohl das Insert schief gelaufen ist. |
AW: [PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Das Grundproblem ist die ungeeignete Erzeugung des Wertes für den Primärschlüssel.
SQL-Code:
Wehe es wird ein Datensatz gelöscht - dann gerät das ganze System durcheinander.
Select count(ID) into c from ...
Besser ist da:
SQL-Code:
Aber auch das ist nicht wasserdicht wenn mehr als ein Prozess/Thread das abarbeitet.
Select Max(ID)+1 into c from ...
Was man hier wirklich bräuchte wäre ein ![]() Dann würde man zuerst mit dem Generator eine "neue Nummer ziehen" und könnte dann sicher sein, dass es keine Kollisionen von anderen Prozessen gibt. |
AW: [PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Zitat:
|
AW: [PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Zitat:
|
AW: [PLSQL] Gibt es ein "Select oder Insert"- Befehl?
Hallo Sirius,
irgendwie passt das nicht zusammen wie Du es beschreibst. Zitat:
Da gibt es zwei Möglichkeiten um das zu prüfen.
SQL-Code:
anderer weg wäre
begin
select ID into result from tabelle where ID = übergabeparameter exception when no_data_found then -- Neuen Datensatz einfügen insert into tabelle ..... end
SQL-Code:
Die ID kommt hoffentlich aus einer Sequenz im Trigger? Sonst einbauen.
declare
vlb_found boolean := false; begin for rec in (select * from tabelle where ID = parameter) loop vlb_found := true; end loop; if not vlb_found then -- neuen Datensatz einfügen insert into tabelle ..... end if; end; Gruß Borwin |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz