Depurar
O que sua função está fazendo pode ser feito muito mais simples. A causa real do erro de sintaxe está aqui:
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;
Parece que você está tentando converter
startDate
para timestamp
, o que é um absurdo para começar, porque seu parâmetro startDate
é declarado como timestamp
já. Também não funciona. Cito o manual aqui :
Ele seria trabalhar assim:
SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;
Mas isso ainda não faria muito sentido. Você está falando sobre "datas", mas ainda define seus parâmetros como
timestamp
. Você poderia higienize o que você tem assim: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
necessário apenas uma vez.date
colunas declaradas como tipo própriodate
.- Não use identificadores de maiúsculas e minúsculas, a menos que você saiba exatamente o que está fazendo.
- Subtraia o início do fim para obter um número positivo ou aplique o operador de valor absoluto
@
. -
Desde a subtração de datas (em vez de subtrair timestamps , que produz uminterval
) já produzinteger
, simplifique para:
SELECT (startDate - endDate) INTO diffDatePart;
Ou ainda mais simples como atribuição plpgsql:
diffDatePart := (startDate - endDate);
Consulta simples
Você pode resolver a tarefa simples com uma consulta simples - usando uma subconsulta:
SELECT (SELECT evt_start_date
FROM events
WHERE evt_id = 6)
- evt_start_date AS date_diff
FROM events
WHERE evt_id = 5;
Ou você pode
CROSS JOIN
a tabela base para si mesma (1 linha de cada instância, então tudo bem):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;
Função SQL
Se você insistir em uma função para esse fim, use uma função sql simples:
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$;
Ligar:
SELECT f_date_diff(5, 6);
Função PL/pgSQL
Se você insistir em 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$;
Mesma chamada.