Postgres DB-Befehl Fehler mit "IF EXISTS"

Fragen und Probleme zu PL/pgSQL.
Antworten
doerflia
Neuer Benutzer
Beiträge: 4
Registriert: Mo 15. Apr 2019, 10:19

Postgres DB-Befehl Fehler mit "IF EXISTS"

Beitrag von doerflia » Di 18. Jun 2019, 09:53

Hi,

vermutlich ein sehr leichter Fehler, aber ich komme nicht dahinter.
Fehlermeldung

Code: Alles auswählen

ERROR: FEHLER: Syntaxfehler bei »IF« LINE 2: IF EXISTS(select * from hd_here.physical_width where hd_... ^ SQL state: 42601 Character: 11
hilft mir auch nicht weiter.

Bin bisher leider nur MySQL gewöhnt und bin mir momentan nicht sicher, ob ich einen groben Denkfehler mache oder das bei Postgres-DBen einfach anders funktioniert.

Mein Code:

Code: Alles auswählen

BEGIN
    IF EXISTS(select * from hd_here.physical_width where hd_here.physical_width.lane_id = '0') THEN
        INSERT into public.hd_link_validation (link_id, a_o_lanes, avg_lane_width_0) VALUES (hd_here.physical_width.lane_group_id, hd_here.physical_width.lane_id, hd_here.physical_width.value)
    END IF

    IF EXISTS(select * from hd_here.physical_width where hd_here.physical_width.lane_id = '1') THEN
        UPDATE public.hd_link_validation SET ao_lanes ='1', avg_lane_width_1 = hd_here.physical_width.value WHERE id = hd_here.physical_width.lane_group_id
	ELSE
	    UPDATE public.hd_link_validation SET ao_lanes ='0', avg_lane_width_1 = '0' WHERE id = hd_here.physical_width.lane_group_id
    END IF

    IF EXISTS(select * from hd_here.physical_width where hd_here.physical_width.lane_id = '2') THEN
        UPDATE public.hd_link_validation SET ao_lanes ='2', avg_lane_width_2 = hd_here.physical_width.value WHERE id = hd_here.physical_width.lane_group_id
	ELSE
	    UPDATE public.hd_link_validation SET ao_lanes ='1', avg_lane_width_2 = '0' WHERE id = hd_here.physical_width.lane_group_id
    END IF

    IF EXISTS(select * from hd_here.physical_width where hd_here.physical_width.lane_id = '3') THEN
        UPDATE public.hd_link_validation SET ao_lanes ='3', avg_lane_width_3 = hd_here.physical_width.value WHERE id = hd_here.physical_width.lane_group_id
	ELSE
	    UPDATE public.hd_link_validation SET ao_lanes ='2', avg_lane_width_3 = '0' WHERE id = hd_here.physical_width.lane_group_id
    END IF
END;
Was ich versuche:
Die Tabelle "hd_link_validation" (Schema: public) zu befüllen.

Die Tabelle hat folgende Struktur:

Code: Alles auswählen

link_id(PK)|a_o_lanes|curvature|predecessor|assesor|avg_road_width|avg_lane_width_0|avg_lane_width_1|avg_lane_width_2|avg_lane_width_3
Die Daten sind in den anderen Tabellen des Schemas "hd_here" vorhanden.
Bspw. in der Tabelle "physical_width"
Mehrere Datensätze in Physical_width können bspw. so aussehen:

Code: Alles auswählen

...|lane_group_id|lane_id|value|...
...|1|0|3.7|...
...|1|1|3.5|...
...|1|2|3.6|...
...|2|0|3.6|...
...|2|1|3.6|...
Wer die Anwendung verstehen will:
"HD_Link_Validation" soll Autobahnabschnitte speichern, dazu die gesamte Anzahl von Spuren, die durchschnittliche Fahrbahnbreite und die durchschnittliche Breite der einzelnen Spuren (0 bis 3). Spur 0 ist der Standstreifen, Spur 1-3 sind die Fahrspuren. Da nicht jede Fahrspur vorhanden ist, wird mit "IF EXISTS" und "ELSE" gearbeitet. In "physical_width" stehen die breiten einzelner Spuren (lane_id). Die "lane_group_id" bündelt mehrere Spuren zu einem Autobahnabschnitt.

Für meine Untersuchung (maschinelles Lernen) brauche ich aber die Daten in einer anderen Struktur (abhängig nur von der lane_group_id), also in der Struktur, die ich in "HD_Link_Validation" vorgegeben habe. Ich möchte dafür einfach nur die Daten (aus anderen Tabellen werden auch noch Infos abgeleitet) so aufbereiten, dass alle Merkmale dafür vorliegen, die ich für ein einfaches Modell brauche.

castorp
Erfahrener Benutzer
Beiträge: 1141
Registriert: Sa 27. Jun 2009, 22:24
Wohnort: Bayern

Re: Postgres DB-Befehl Fehler mit "IF EXISTS"

Beitrag von castorp » Di 18. Jun 2019, 10:37

IF oder BEGIN sind keine SQL Befehle, sondern PL/pgSQL Anweisungen. Wenn das nicht Teil einer Funktion/Prozedur ist, dann klappt das so sowieso nicht. Wenn das Teil einer Funktion ist, dann zeig uns bitte den komplette code.

Letztendlich brauchst Du aber gar kein IF EXISTS. Wenn ich das richtig verstehe kannst Du das durch INSERT ON CONFLICT DO NOTHING bzw. INSERT ON CONFLICT DO UPDATE ersetzen.
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

pogomips
Erfahrener Benutzer
Beiträge: 105
Registriert: Fr 18. Nov 2016, 09:55

Re: Postgres DB-Befehl Fehler mit "IF EXISTS"

Beitrag von pogomips » Fr 21. Jun 2019, 09:06

Ein paar Anmerkungen:
1. Ein Begin/End könnte auch ein anonymer Block sein. Ich weiß nicht seit wann mySQL das könnte (vielleicht >8?), pg kann es jedenfalls schon ewig. Nur nicht so, wie hier geschrieben
2. Wenn 1, dann würde auch ein if then else funktionieren
3. Es wäre aber wie schon geschrieben tatsächlich nicht nötig
4. Es wäre wahrscheinlich auch keine Kleinklein mit on conflict nötig
5. Auch wenn ich den Sinn des Statements und die Richtigkeit der Einzelschritte bezweifel (vermutlich ist der "Reifegrad" des gezeigt SQL wegen der grundsätzlichen Fehler noch gering), man kann es wahrscheinlich mit einem einzigen aggregierenden Select durchführen, also nur Insert ohne updates, vielleicht mit Case
6. Wg 5. dann sicher auch schnell(er)

doerflia
Neuer Benutzer
Beiträge: 4
Registriert: Mo 15. Apr 2019, 10:19

Re: Postgres DB-Befehl Fehler mit "IF EXISTS"

Beitrag von doerflia » Do 11. Jul 2019, 11:37

Kann ich das Thema selbst schließen, wenn ich mein Problem inzwischen lösen konnte?

castorp
Erfahrener Benutzer
Beiträge: 1141
Registriert: Sa 27. Jun 2009, 22:24
Wohnort: Bayern

Re: Postgres DB-Befehl Fehler mit "IF EXISTS"

Beitrag von castorp » Do 11. Jul 2019, 11:45

Wenn Du eine Lösung gefunden hast, dann wäre es nur nett, wenn Du sie uns auch verrätst und hier reinschreibst.

Einen Status "gelöst" gibt es hier meines Wissens nach nicht
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

Antworten