Debuggen
Was Ihre Funktion tut, könnte viel tun einfacher. Die eigentliche Ursache für den Syntaxfehler ist hier:
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;
Es sieht so aus, als ob Sie versuchen, startDate
zu casten zu timestamp
, was zunächst Unsinn ist, weil Ihr Parameter startDate
wird als timestamp
deklariert schon.
Es funktioniert auch nicht. Ich zitiere das Handbuch hier :
Es würde funktioniert so:
SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;
Aber das würde noch nicht viel Sinn machen. Sie sprechen von "Daten", definieren Ihre Parameter aber immer noch als timestamp
. Sie könnten säubern Sie, was Sie haben, wie folgt:
CREATE OR REPLACE FUNCTION f_date_diff()
RETURNS int AS
$BODY$
DECLARE
start_date date;
end_date date;
date_diff int;
BEGIN
SELECT evt_start_date FROM events WHERE evt_id = 5 INTO start_date;
SELECT evt_start_date FROM events WHERE evt_id = 6 INTO end_date;
date_diff := (endDate - startDate);
RETURN date_diff;
END
$BODY$ LANGUAGE plpgsql;
DECLARE
nur einmal benötigt.date
Spalten, die als richtiger Typdate
deklariert sind .- Verwenden Sie keine Groß-/Kleinschreibung, es sei denn, Sie wissen genau, was Sie tun.
- Subtrahieren Sie den Start vom Ende um eine positive Zahl zu erhalten, oder wenden Sie den Absolutwertoperator
@
. -
Seit dem Subtrahieren von Daten (im Gegensatz zum Subtrahieren von Zeitstempeln , was ein
interval
ergibt ) ergibt bereitsinteger
, vereinfachen zu:SELECT (startDate - endDate) INTO diffDatePart;
Oder noch einfacher als plpgsql-Zuweisung:
diffDatePart := (startDate - endDate);
Einfache Abfrage
Sie können die einfache Aufgabe mit einer einfachen Abfrage lösen - mit einer Unterabfrage:
SELECT (SELECT evt_start_date
FROM events
WHERE evt_id = 6)
- evt_start_date AS date_diff
FROM events
WHERE evt_id = 5;
Oder Sie könnten CROSS JOIN
die Basistabelle für sich selbst (1 Zeile von jeder Instanz, also ist das in Ordnung):
SELECT e.evt_start_date - s.evt_start_date AS date_diff
FROM events e
,events s
WHERE e.evt_id = 6
AND s.evt_id = 5;
SQL-Funktion
Wenn Sie zu diesem Zweck auf einer Funktion bestehen, verwenden Sie eine einfache SQL-Funktion:
CREATE OR REPLACE FUNCTION f_date_diff(_start_id int, _end_id int)
RETURNS int LANGUAGE sql AS
$func$
SELECT e.evt_start_date - s.evt_start_date
FROM events s, events e
WHERE s.evt_id = $1
AND e.evt_id = $2
$func$;
Aufruf:
SELECT f_date_diff(5, 6);
PL/pgSQL-Funktion
Wenn Sie auf plpgsql bestehen ...
CREATE OR REPLACE FUNCTION f_date_diff(_start_id int, _end_id int)
RETURNS int LANGUAGE plpgsql AS
$func$
BEGIN
RETURN (SELECT evt_start_date
- (SELECT evt_start_date FROM events WHERE evt_id = _start_id)
FROM events WHERE evt_id = _end_id);
END
$func$;
Gleicher Aufruf.