如果您想要使用PL/pgSQL的过程特性,您需要将语言从
sql
更改为
plpgsql
。函数主体也会发生变化。
请注意,在函数主体中
所有参数名称都是可见的,包括所有级别的SQL语句。如果出现命名冲突,您可能需要像这样对列名进行表限定:
table.col
,以避免混淆。由于您通过位置引用(
$n
)来引用函数参数, 所以我只是移除了参数名以使其正常工作。
最后,
IF
语句中缺少
THEN
- 这是错误消息的
直接原因。
可以使用
COALESCE来替换
NULL
值。但这仅在至少有一个结果行时才起作用。
COALESCE
无法修复“无行”,它只能替换实际的
NULL
值。
有几种方法可以覆盖所有
NULL
情况。在
plpgsql函数中:
CREATE OR REPLACE FUNCTION point_total(integer, date, OUT result bigint)
RETURNS bigint AS
$func$
BEGIN
SELECT sum(p.points)
INTO result
FROM picks p
WHERE p.user_id = $1
AND p.gametime > $2
AND p.points IS NOT NULL;
IF NOT FOUND THEN
result := 0;
END IF;
END
$func$ LANGUAGE plpgsql;
或者您可以将整个查询语句放在外部 SELECT
中的 COALESCE
表达式中。内部 SELECT
的“无行”结果将导致表达式中的 NULL
。它可以作为普通SQL工作,或者您可以将其封装在一个 SQL函数 中:
CREATE OR REPLACE FUNCTION point_total(integer, date)
RETURNS bigint AS
$func$
SELECT COALESCE(
(SELECT sum(p.points)
FROM picks p
WHERE p.user_id = $1
AND p.gametime > $2
), 0)
$func$ LANGUAGE sql;
相关回答:
关于命名冲突
一个问题很可能是命名冲突。在9.0版本中有重大变化。我引用发布说明:
E.8.2.5. PL/pgSQL
如果一个变量名与查询中使用的列名冲突,PL/pgSQL现在会抛出错误 (Tom Lane)
后续版本已经完善了这种行为。在明显的情况下,适当的替代方案会被自动选择。这减少了冲突的潜力,但仍然存在。在Postgres 9.3中仍然适用这个建议。