Ladění
To, co vaše funkce dělá, by se dalo udělat hodně jednodušší. Skutečná příčina syntaktické chyby je zde:
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;
Zdá se, že se pokoušíte odeslat startDate
na timestamp
, což je pro začátek nesmysl, protože váš parametr startDate
je deklarován jako timestamp
již.
To také nejde. Cituji příručku zde :
by pracovat takto:
SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;
Ale to by stejně nedávalo moc smysl. Mluvíte o "datech", ale přesto definujte své parametry jako timestamp
. Mohli byste dezinfikujte to, co máte, takto:
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
potřeba pouze jednou.date
sloupce deklarované jako správný typdate
.- Nepoužívejte smíšené identifikátory velkých a malých písmen, pokud přesně nevíte, co děláte.
- Odečtěte začátek od konce získat kladné číslo nebo použít operátor absolutní hodnoty
@
. -
Od odečtení dat (na rozdíl od odečítání časových razítek , což dává
interval
) již dáváinteger
, zjednodušte na:SELECT (startDate - endDate) INTO diffDatePart;
Nebo ještě jednodušší jako přiřazení plpgsql:
diffDatePart := (startDate - endDate);
Jednoduchý dotaz
Jednoduchý úkol můžete vyřešit jednoduchým dotazem – pomocí poddotazu:
SELECT (SELECT evt_start_date
FROM events
WHERE evt_id = 6)
- evt_start_date AS date_diff
FROM events
WHERE evt_id = 5;
Nebo se můžete CROSS JOIN
základní tabulka pro sebe (1 řádek z každé instance, takže je to v pořádku):
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;
Funkce SQL
Pokud trváte na funkci pro tento účel, použijte jednoduchou funkci SQL:
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$;
Volejte:
SELECT f_date_diff(5, 6);
Funkce PL/pgSQL
Pokud trváte na 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$;
Stejný hovor.