Debugowanie
To, co robi Twoja funkcja, można zrobić dużo prostsze. Rzeczywista przyczyna błędu składni jest tutaj:
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;
Wygląda na to, że próbujesz przesłać startDate
do timestamp
, co na początku jest nonsensem, ponieważ Twój parametr startDate
jest zadeklarowany jako timestamp
już.
To też nie działa. Cytuję instrukcję tutaj :
byłoby działaj tak:
SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;
Ale to nadal nie miałoby sensu. Mówisz o „datach”, ale nadal definiujesz swoje parametry jako timestamp
. możesz zdezynfekuj to, co masz w ten sposób:
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
potrzebne tylko raz.date
kolumny zadeklarowane jako właściwy typdate
.- Nie używaj identyfikatorów wielkości liter, chyba że wiesz dokładnie, co robisz.
- Odejmij początek od koniec aby uzyskać liczbę dodatnią lub zastosować operator wartości bezwzględnej
@
. -
Od odjęcia dat (w przeciwieństwie do odejmowania sygnatur czasowych , co daje
interval
) już zwracainteger
, uprość do:SELECT (startDate - endDate) INTO diffDatePart;
Lub jeszcze prostsze, jak przypisanie plpgsql:
diffDatePart := (startDate - endDate);
Proste zapytanie
Możesz rozwiązać proste zadanie za pomocą prostego zapytania - używając podzapytania:
SELECT (SELECT evt_start_date
FROM events
WHERE evt_id = 6)
- evt_start_date AS date_diff
FROM events
WHERE evt_id = 5;
Możesz też CROSS JOIN
podstawowa tabela do siebie (1 wiersz z każdej instancji, więc jest ok):
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;
Funkcja SQL
Jeśli nalegasz na jakąś funkcję do tego celu, użyj prostej funkcji 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$;
Zadzwoń:
SELECT f_date_diff(5, 6);
Funkcja PL/pgSQL
Jeśli nalegasz 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$;
To samo połączenie.