我有一个功能:
CREATE OR REPLACE FUNCTION eventidswithinradius(
lat double precision,
lng double precision,
radius double precision DEFAULT 10000.0)
RETURNS SETOF bigint AS
$BODY$
SELECT event.event_id
FROM event
JOIN location l USING (location_id)
WHERE earth_box(ll_to_earth(lat, lng),
CASE WHEN radius > 100000.0 OR radius < 1 THEN 10000.0 ELSE radius END
) @> ll_to_earth(l.latitude, l.longitude);
$BODY$
LANGUAGE sql VOLATILE STRICT
COST 100
ROWS 1000;
我希望使用事件start_date
和end_date
的两个可选参数来扩展它,其默认参数值为NULL
。所以我写了这个:
CREATE OR REPLACE FUNCTION eventidswithinradius1(
lat double precision,
lng double precision,
radius double precision DEFAULT 10000.0,
e_start_date date DEFAULT NULL,
e_end_date date DEFAULT NULL)
RETURNS SETOF bigint AS
$BODY$
SELECT event.event_id
FROM event
JOIN location l USING (location_id)
WHERE earth_box(ll_to_earth(lat, lng),
CASE WHEN radius > 100000.0 OR radius < 1 THEN 10000.0 ELSE radius END
) @> ll_to_earth(l.latitude, l.longitude);
$BODY$
LANGUAGE sql VOLATILE STRICT
COST 100
ROWS 1000;
注意:我只添加了两个参数,但我还没有使用它们。
但是现在当我使用相同的参数运行两个函数时,即:
SELECT * FROM eventidswithinradius(40.1234, 15.2131, 100000.0);
SELECT * FROM eventidswithinradius1(40.1234, 15.2131, 100000.0);
只有第一个返回任何数据。第二个返回一个空表。
我也尝试使用varchar
而不是两个日期添加单个测试DEFAULT NULL
参数,并且发生了同样的事情。
谁能告诉我这里发生了什么?我以为PostgreSQL不支持多个默认参数,但检查documentation我发现Functions can be declared with default values for some or all input arguments.
所以这应该可以清楚地工作。
经过进一步调查,添加没有DEFAULT
的日期参数有效,所以我假设不允许NULL为默认值?
答案 0 :(得分:1)
请注意以下http://www.postgresql.org/docs/9.4/static/sql-createfunction.html:
调用NULL输入,在NULL输入时返回NULL , STRICT
CALLED ON NULL INPUT(默认值)表示将调用该函数 通常当它的一些参数为null时。那就是功能 如有必要,作者有责任检查空值 适当回应。
RETURNS NULL ON NULL INPUT或STRICT表示该函数 每当任何参数为null时,它总是返回null。如果这 指定参数,有时不执行该功能 null参数;而是自动假设空结果。
所以在你的情况下用 CALLED ON NULL INPUT 替换 STRICT 并在函数内部自己执行空值检查。