Các tính năng nâng cao như VARIADIC
hoặc thậm chí các kiểu đầu vào đa hình và SQL động rất mạnh mẽ. Chương cuối cùng trong câu trả lời này cung cấp một ví dụ nâng cao:
- Cấu trúc lại một hàm PL / pgSQL để trả về kết quả đầu ra của các truy vấn SELECT khác nhau
Nhưng đối với trường hợp đơn giản như của bạn, bạn chỉ có thể sử dụng giá trị mặc định cho các tham số chức năng. Tất cả phụ thuộc vào yêu cầu chính xác.
Nếu tất cả các cột được đề cập đều được xác định NOT NULL
, điều này có thể sẽ đơn giản hơn và nhanh hơn:
CREATE OR REPLACE FUNCTION update_site(_name text -- always required
, _city text DEFAULT NULL
, _telephone integer DEFAULT NULL)
RETURNS integer AS
$func$
BEGIN
IF _city IS NULL AND _telephone IS NULL THEN
RAISE WARNING 'At least one value to update required!';
RETURN; -- nothing to update
END IF;
UPDATE "Sites"
SET "City" = COALESCE(_city, "City")
, "Telephone" = COALESCE(_telephone, "Telephone")
WHERE "SiteName" = _name;
END
$func$ LANGUAGE plpgsql;
Đọc về các giá trị mặc định trong sách hướng dẫn!
Để tránh xung đột đặt tên giữa các tham số và tên cột, tôi có thói quen đặt trước các tham số đầu vào bằng _
. Đó là vấn đề về sở thích và phong cách.
- Tham số đầu tiên
name
không có mặc định, vì nó luôn được yêu cầu. - Có thể bỏ qua các thông số khác.
- Bắt buộc phải có ít nhất một hoặc một
WARNING
được nâng lên và không có gì khác xảy ra. -
UPDATE
sẽ chỉ thay đổi các cột cho các thông số nhất định. - Có thể dễ dàng mở rộng cho N tham số.
Lệnh gọi hàm
Kể từ Postgres 9.5 :
Cách đơn giản là với ký hiệu vị trí cho các tham số. Điều này chỉ cho phép bỏ qua (các) tham số ngoài cùng bên phải:
SELECT update_site('foo', 'New York'); -- no telephone
Ký hiệu được đặt tên cho phép bỏ qua bất kỳ tham số có giá trị mặc định:
SELECT update_site(name => 'foo', _telephone => 123); -- no city
Cả hai đều có thể được kết hợp trong ký hiệu hỗn hợp :
SELECT update_site('foo', _telephone => 123); -- still no city
Trong Postgres 9.4 trở lên, :=
đã được sử dụng để chỉ định trong cuộc gọi:
SELECT update_site(name := 'foo', _telephone := 123);
SELECT update_site('foo', _telephone := 123);
Vẫn còn hiệu lực trong Postgres 12 để tương thích ngược, nhưng sử dụng ký hiệu hiện đại hơn.