Kể từ PostgreSQL 8.4 (mà bạn dường như đang chạy), có giá trị mặc định cho các tham số hàm . Nếu bạn đặt tham số cuối cùng và cung cấp tham số mặc định, bạn chỉ cần bỏ qua tham số đó khỏi lệnh gọi:
CREATE OR REPLACE FUNCTION foofunc(_param1 integer
, _param2 date
, _ids int[] DEFAULT '{}')
RETURNS SETOF foobar -- declare return type!
LANGUAGE plpgsql AS
$func$
BEGIN -- required for plpgsql
IF _ids <> '{}'::int[] THEN -- exclude empty array and NULL
RETURN QUERY
SELECT *
FROM foobar
WHERE f1 = _param1
AND f2 = _param2
AND id = ANY(_ids); -- "IN" is not proper syntax for arrays
ELSE
RETURN QUERY
SELECT *
FROM foobar
WHERE f1 = _param1
AND f2 = _param2;
END IF;
END -- required for plpgsql
$func$;
Những điểm chính:
-
Từ khóa
DEFAULT
được sử dụng để khai báo giá trị mặc định của tham số. Thay thế ngắn:=
. -
Tôi đã xóa
param1
thừa từ ví dụ lộn xộn. -
Vì bạn trả về
SELECT * FROM foobar
, khai báo kiểu trả về làRETURNS SETOF foobar
thay vì bản ghiRETURNS SETOF record
. Biểu mẫu thứ hai với các bản ghi ẩn danh rất khó sử dụng, bạn phải cung cấp danh sách định nghĩa cột với mỗi lần gọi. -
Tôi sử dụng một mảng số nguyên (
int[]
) dưới dạng tham số hàm. Đã điều chỉnhIF
biểu thức vàWHERE
mệnh đề phù hợp. -
IF
câu lệnh không có sẵn trong SQL thuần túy. Phải làLANGUAGE plpgsql
cho điều đó.
Gọi có hoặc không có _ids
:
SELECT * FROM foofunc(1, '2012-1-1'::date);
Hiệu quả như nhau:
SELECT * FROM foofunc(1, '2012-1-1'::date, '{}'::int[]);
Bạn phải đảm bảo cuộc gọi không rõ ràng. Nếu bạn có một hàm khác có cùng tên và hai tham số, Postgres có thể không biết nên chọn hàm nào. Truyền rõ ràng (như tôi chứng minh) thu hẹp nó. Khác, các ký tự chuỗi không định kiểu cũng hoạt động, nhưng rõ ràng không bao giờ gây hại.
Gọi từ bên trong một chức năng khác:
CREATE FUNCTION foofuncwrapper(_param1 integer, _param2 date)
RETURNS SETOF foobar
LANGUAGE plgpsql AS
$func$
DECLARE
_ids int[] := '{1,2,3}';
BEGIN
-- whatever
RETURN QUERY
SELECT * FROM foofunc(_param1, _param2, _ids);
END
$func$;