SQL-Query: syntax error

Moin, moin,

in einem Skript habe ich folgende Query:

SELECT CASE 
	WHEN (ip='1.2.3.4' AND hostname='' AND page='/PHPSkripte/wetterdienst_karte.php' AND ssl=1 AND parameter='GET:typ=warnkarte;lkz=DE-BAYALPEN') THEN
		UPDATE t_system_zugriff SET zaehler=zaehler+1,synctime_tz=now(),synctime=unix_timestamp() WHERE ip='1.2.3.4' AND hostname='' AND page='/PHPSkripte/wetterdienst_karte.php' AND ssl=1 AND parameter='GET:typ=warnkarte;lkz=DE-BAYALPEN'
	ELSE
		INSERT INTO t_system_zugriff (ip, hostname, zaehler, synctime_dt, synctime, page, ssl, parameter) VALUES ('1.2.3.4','',1,now(),unix_timestamp(),'/PHPSkripte/wetterdienst_karte.php',1,'GET:typ=warnkarte;lkz=DE-BAYALPEN')
	END
FROM
	t_system_zugriff

Wenn die Query ausgeführt wird kommt die Fehlermeldung:

ERROR: FEHLER: Syntaxfehler bei »t_system_zugriff«
ZEILE 3: UPDATE t_system_zugriff SET zaehler=zaehler+1,synctime_dt=…
SQL state: 42601
Character: 178

Wo steckt da der Fehler? Ich sehe ihn nicht.

Danke für Eure Hilfe.

JueDan

Du kannst nicht INSERT oder UPDATE statements in ein SELECT integrieren. Du brauchst entweder PL/pgSQL dafür, oder Du verwendest INSERT ... ON CONFLICT do update .... Unter der Annahme, dass es einen unique index (oder constraint) auf (ip, hostname, page, ssl, parameter) gibt, müsste das so aussehen:

INSERT INTO t_system_zugriff 
  (ip, hostname, zaehler, synctime_dt, synctime, page, ssl, parameter) 
VALUES 
  ('1.2.3.4','',1,now(), extract(epoch from now()),'/PHPSkripte/wetterdienst_karte.php',1,'GET:typ=warnkarte;lkz=DE-BAYALPEN')
ON CONFLICT (ip, hostname, page, ssl, parameter)
DO UPDATE 
	SET zaehler = t_system_zugriff.zaehler+1,
      synctime_tz = now(),
      synctime = extract(epoch from now());

Ausserdem ist unix_timestamp() keine (standard) Postgres Funktion (auch erschließt sich mir der Sinn nicht die Information von “now()” zu duplizieren)

Hallo castorp,

danke für die Antwort. Jetzt verstehe ich die Fehlermeldung “ERROR: FEHLER: Syntaxfehler bei »t_system_zugriff«”.
Ich habe immer soetwas wie das von MySQL bekannte " INSERT … ON DUPLICATE KEY UPDATE…" gesucht. Deswegen habe ich mir die Sache mit SELECT… ausgedacht.

In der PostgreSQL-Dokumentation steht das nicht im Abschnitt “6. Data Manipulation -> 6.1. Inserting Data”. Erst wenn man weiß, dass man “ON CONFLICT” nehmen muss, dann findet man das auch.

unix_timestamp() hatte ich mal geschrieben, um Queries - für mich - übersichtlicher zu machen und um Queries von MySQL leichter zu PG zu übertragen.

Beste Grüße

JueDan aka Jürgen

Grundsätzlich ist das Speichern von timestamps als bigint eine schlechte Idee. Dafür gibt es den Datentyp timestamp bzw. besser not timestamp with time zone

Ich persönlich find eine Angabe wie where synctime_tz > timestamp '2020-09-05 11:12:13' wesentlich übersichtlicher und leichter zu lesen als where synctime_tz > 1599304333.

Man kann sehr einfach ein timestamp in ein “Unix epoch” verwandeln, das muss man nicht doppelt speichern.

Einen anderen Grund hatte ich noch vergessen: Ursprünglich war das gesamte Projekt auf MySQL ausgerichtet, weil mein damaliger Provider nur MySQL zur Verfügung stellte. Und da sah ich nur die Lösung mit synctime als bigint. Inzwischen läuft die komplette Anwendung auf meinem Server unter PostgreSQL und ich bin da schrittweise am Anpassen.
Ich gebe Dir Recht, dass die von dir genannte Query mindestens genauso gut zu lesen ist. In den Daten sind aber auch Unix-Timestamps drin und ich fand es dann einfacher so zumachen, wie beschrieben.
Aber ich bin wie geschrieben am Anpassen :grin:

Beste Grüße

JueDan aka Jürgen