[英]Functions with variable number of input parameters
我正在 PostgreSQL 数据库中创建一个存储过程(函数),它根据输入更新表。 为了创建可变数量的参数函数,我创建了一个名为 mode 的额外输入参数,我用它来控制我在更新查询中使用的参数。
CREATE OR REPLACE FUNCTION update_site(
mode integer,
name character varying,
city character varying,
telephone integer,
)
RETURNS integer AS
$$
BEGIN
IF mode = 0 THEN
BEGIN
UPDATE "Sites" SET
("City","Telephone") = (city,telephone)
WHERE "SiteName" = name;
RETURN 1;
EXCEPTION WHEN others THEN
RAISE NOTICE 'Error on site update: %, %',SQLERRM,SQLSTATE;
RETURN 0;
END;
ELSIF mode = 1 THEN
BEGIN
UPDATE "Sites" SET "City" = city
WHERE "SiteName" = name;
RETURN 1;
EXCEPTION WHEN others THEN
RAISE NOTICE 'Error on site update: %, %',SQLERRM,SQLSTATE;
RETURN 0;
END;
ELSIF mode = 2 THEN
BEGIN
UPDATE "Sites" SET "Telephone" = telephone
WHERE "SiteName" = name;
RETURN 1;
EXCEPTION WHEN others THEN
RAISE NOTICE 'Error on site update: %, %',SQLERRM,SQLSTATE;
RETURN 0;
END;
ELSE
RAISE NOTICE 'Error on site update: %, %',SQLERRM,SQLSTATE;
RETURN 0;
END IF;
END;
$$ LANGUAGE plpgsql;
什么是最好的? 要创建一个函数update_site(<all the columns of table>)
和一个单独的函数update_site(id integer, <varchar column to update>)
,还是使用一个函数中的模式来定义差异? 哪个选项更有效? 一种独特的功能还是针对每种用途的不同功能?
VARIADIC
甚至多态输入类型和动态 SQL 等高级功能都非常强大。 本答案的最后一章提供了一个高级示例:
但是对于像您这样的简单情况,您可以只使用函数参数的默认值。 这一切都取决于确切的要求。
如果有问题的列都定义为NOT NULL
,这可能会更简单、更快:
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;
阅读手册中的默认值!
为了避免参数和列名之间的命名冲突,我习惯于在输入参数前加上_
。 这是品味和风格的问题。
name
没有默认值,因为它始终是必需的。WARNING
并且没有其他任何事情发生。UPDATE
只会更改给定参数的列。从Postgres 9.5 开始:
简单的方法是使用参数的位置符号。 这只允许省略最右边的参数:
SELECT update_site('foo', 'New York'); -- no telephone
命名符号允许省略任何具有默认值的参数:
SELECT update_site(name => 'foo', _telephone => 123); -- no city
两者都可以混合表示法组合:
SELECT update_site('foo', _telephone => 123); -- still no city
在Postgres 9.4或更早版本中, :=
用于调用中的赋值:
SELECT update_site(name := 'foo', _telephone := 123);
SELECT update_site('foo', _telephone := 123);
为了向后兼容,在 Postgres 12 中仍然有效,而是使用现代表示法。
您需要了解以下几点:
使用format
函数及其%I
和%L
说明符动态构建 SQL,然后使用EXECUTE ... USING
执行它; 和
使用VARIADIC
参数将可变数量的参数传递给函数,但需要注意的是它们都必须是相同的数据类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.