Problem mit verketteten Insert statements

Steffen

Neuer Benutzer
Beiträge
4
Ich möchte die Tabelle ‚Zahlungen‘ aus zwei anderen Tabellen ergänzen, so dass nur Records angelegt werden, die nicht schon existieren.

Beide unten aufgeführten Insert Into Statements funktionieren perfekt, aber immer nur eins für sich.
Wenn ich beide zusammen ausführe, liefert das jeweils zweite keine Records.
Das gilt auch, wenn ich die Reihenfolge umkehre.

Auch ein "Commit" statement dazwischen hilft nichts.

Insert into zahlungen(Name, Vorname, Bezugsjahr)
Select distinct name, vorname, 2025 from Spinde
where not exists(Select Name, Vorname, Bezugsjahr from Zahlungen where Bezugsjahr = '2025');

Insert into zahlungen(Name, Vorname, Bezugsjahr)
Select distinct name, vorname, 2025 from Boote
where not exists(Select Name, Vorname, Bezugsjahr from Zahlungen where Bezugsjahr = '2025');

Hat jemand eine Idee, woran das liegt bzw. was fehlt?
Steffen
 
Werbung:
Im ersten Statement erzeugst Du ja Einträge mit Bezugsjahr = 2025, im zweiten machst Du den INSERT nur, wenn es noch keine Einträge für das Jahr gibt - aber nachdem Du die im ersten Schritt erzeugt hast, existieren die und das NOT EXISTS ist "falsch".

Sub-Queries für EXISTS oder NOT EXISTS die nicht Bezug nehmen auf das äussere Statement ("co-related subquery") sind eigentlich immer ein Fehler. Im Übrigen reicht im Sub-Query ein SELECT * - die Werte die da zurückkommen sind irrelevant und werden ignoriert.
 
Da in der zweiten Tabelle teilweise andere User stehen, sollten die noch fehlenden eigentlich trotzdem ergänzt werden.
Wenn die Felder aber ignoriert werden, klappt das natürlich nicht.

Habe die beiden Skripte jetzt per co-related subquery versehen, leider ohne Erfolg: Das jeweils zweite wird immer noch nicht ausgeführt.
Leider habe ich keine ID, sondern verknüpfe über Name+Vorname:

Insert into zahlungen(Name, Vorname, Bezugsjahr)
Select distinct s.name, s.vorname, 2025 from Spinde s
where not exists(Select * from Zahlungen z where s.name+s.vorname = z.name+z.vorname and Bezugsjahr = '2025' );

Insert into zahlungen(Name, Vorname, Bezugsjahr)
Select distinct B.name, B.vorname, 2025 from Boote b
where not exists(Select * from Zahlungen z where b.name+b.vorname = z.name+z.vorname and Bezugsjahr = '2025' );
?
 
leider ohne Erfolg
Wie führst Du die denn aus?
sql console oder - tool oder in irgendeiner Programmiersprache?

Eine Idee:
Meist kann ein SQL Client für eine Programmiersprache xy nur jeweils ein Statement verarbeiten. Alles nach dem ersten Semicolon ist egal, Fehler, ..
Oft ist bereits das erste Semicolon ein Fehler. (Wenn Du keine Fehlerbehandlung im Programmcode hast, fällt es nicht auf)

Falls es daran liegt, würden auch bei zwei bedingungslosen Inserts mit Konstanten nur das erste eingetragen. Also Fehler im Programmcode / Vorgehen. Werden beide eingetragen, sind die Bedingungen in den beiden Statements (so) nicht unabhängig, wie Du glaubst.
 
... sowohl mit 'SQL-ausführen' mit "DB Browser für SQLite" als auch als Query im neuesten Delphi 12.
Selbst wenn ich in Delphi zwei getrennte SQL-Queries mit jeweils nur einem Skript ausführe, klappt es beim zweiten nicht.
Habe auch beim ersten Statement das Semikolon weggelassen.

Es muss doch irgendwas mit der Syntax falsch sein... 😕
 
Was ist wenn Du die Spalten einzeln vergleichst anstatt sie mit + zu verbinden?

Code:
Insert into zahlungen(Name, Vorname, Bezugsjahr)
Select distinct B.name, B.vorname, 2025
from Boote b
where not exists(Select *
                 from Zahlungen z
                 where b.name = z.name
                   and b.vorname = z.vorname
                   and z.Bezugsjahr = '2025' );

Kann name oder vorname NULL sein?

Aber wenn es den Benutzer bereits in Spinde gab, dann gibt es die Kombination ja auch schon (wegen dem ersten Statement)
 
Aber wenn es den Benutzer bereits in Spinde gab, dann gibt es die Kombination ja auch schon (wegen dem ersten Statement)
Das könnte man dadurch lösen, dass Du als Quelle für das INSERT gleich ein UNION beider Tabellen verwendest:

Code:
Insert into zahlungen(Name, Vorname, Bezugsjahr)
select *
from (
  Select s.name, s.vorname, 2025 as bezugsjahr
  from Spinde s
  union 
  Select B.name, B.vorname, 2025 
  from Boote b
) as sb
where not exists(Select *
                 from Zahlungen z
                  where sb.name = z.name
                    and sb.vorname = z.vorname
                    and z.Bezugsjahr = '2025' );
 
Werbung:
Was ist wenn Du die Spalten einzeln vergleichst anstatt sie mit + zu verbinden?

Code:
Insert into zahlungen(Name, Vorname, Bezugsjahr)
Select distinct B.name, B.vorname, 2025
from Boote b
where not exists(Select *
                 from Zahlungen z
                 where b.name = z.name
                   and b.vorname = z.vorname
                   and z.Bezugsjahr = '2025' );

Kann name oder vorname NULL sein?

Aber wenn es den Benutzer bereits in Spinde gab, dann gibt es die Kombination ja auch schon (wegen dem ersten Statement)
Danke Castorp, so funktioniert es!
 
Zurück
Oben