Gỡ lỗi
Những gì chức năng của bạn đang làm có thể được thực hiện nhiều đơn giản hơn. Nguyên nhân thực sự của lỗi cú pháp là ở đây:
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;
Có vẻ như bạn đang cố truyền startDate
đến timestamp
, điều này thật vô lý khi bắt đầu, bởi vì tham số startDate
của bạn được khai báo là timestamp
đã.
Nó cũng không hoạt động. Tôi trích dẫn hướng dẫn ở đây :
Nó sẽ làm việc như thế này:
SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;
Nhưng điều đó vẫn không có nhiều ý nghĩa. Bạn đang nói về "ngày tháng", nhưng vẫn xác định các thông số của bạn là timestamp
. Bạn có thể vệ sinh những gì bạn có như sau:
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
chỉ cần một lần. -
date
các cột được khai báo là loại phù hợpdate
. - Không sử dụng các mã nhận dạng chữ hoa chữ thường hỗn hợp, trừ khi bạn biết chính xác mình đang làm gì.
- Trừ số bắt đầu từ end để nhận một số dương hoặc áp dụng toán tử giá trị tuyệt đối
@
. -
Kể từ khi trừ đi ngày tháng (trái ngược với việc trừ dấu thời gian , tạo ra một
interval
) đã mang lạiinteger
, đơn giản hóa thành:SELECT (startDate - endDate) INTO diffDatePart;
Hoặc thậm chí đơn giản hơn như gán plpgsql:
diffDatePart := (startDate - endDate);
Truy vấn đơn giản
Bạn có thể giải quyết công việc đơn giản bằng một truy vấn đơn giản - sử dụng truy vấn con:
SELECT (SELECT evt_start_date
FROM events
WHERE evt_id = 6)
- evt_start_date AS date_diff
FROM events
WHERE evt_id = 5;
Hoặc bạn có thể CROSS JOIN
bảng cơ sở cho chính nó (1 hàng từ mỗi phiên bản, vậy là được):
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;
Hàm SQL
Nếu bạn nhấn mạnh vào một hàm cho mục đích, hãy sử dụng một hàm sql đơn giản:
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$;
Gọi:
SELECT f_date_diff(5, 6);
Hàm PL / pgSQL
Nếu bạn nhấn mạnh vào 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$;
Cùng một cuộc gọi.