Foutopsporing
Wat uw functie doet, kan veel worden gedaan eenvoudiger. De werkelijke oorzaak van de syntaxisfout is hier:
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;
Het lijkt erop dat je startDate
probeert te casten naar timestamp
, wat in het begin onzin is, omdat uw parameter startDate
wordt gedeclareerd als timestamp
al.
Het werkt ook niet. Ik citeer de handleiding hier :
Het zou werk als volgt:
SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;
Maar dat zou nog niet veel zin hebben. Je hebt het over "datums", maar definieert je parameters nog steeds als timestamp
. Je zou ontsmet wat je hebt als volgt:
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
slechts één keer nodig.date
kolommen gedeclareerd als het juiste typedate
.- Gebruik geen hoofdletter-ID's, tenzij u precies weet wat u doet.
- Trek de start af vanaf het einde om een positief getal te krijgen of de absolute value-operator
@
. -
Sinds het aftrekken van datums (in tegenstelling tot het aftrekken van tijdstempels , wat een
interval
. oplevert ) levert alinteger
op , vereenvoudigen tot:SELECT (startDate - endDate) INTO diffDatePart;
Of nog eenvoudiger als plpgsql-opdracht:
diffDatePart := (startDate - endDate);
Eenvoudige vraag
U kunt de eenvoudige taak oplossen met een eenvoudige query - met behulp van een subquery:
SELECT (SELECT evt_start_date
FROM events
WHERE evt_id = 6)
- evt_start_date AS date_diff
FROM events
WHERE evt_id = 5;
Of je kunt CROSS JOIN
de basistabel naar zichzelf (1 rij van elke instantie, dus dat is goed):
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-functie
Als je een functie voor dit doel wilt gebruiken, gebruik dan een eenvoudige sql-functie:
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$;
Bel:
SELECT f_date_diff(5, 6);
PL/pgSQL-functie
Als je aandringt op plpgsql ...
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$;
Zelfde oproep.