Postgresql Postgres函数始终返回一行
我在Postgres中编写了以下函数,但我遇到了一个问题:它总是返回一行。我的意思是,当没有用户匹配该对时,它返回一行,所有列都为空 当没有结果时,有没有办法使函数返回0(零)行Postgresql Postgres函数始终返回一行,postgresql,Postgresql,我在Postgres中编写了以下函数,但我遇到了一个问题:它总是返回一行。我的意思是,当没有用户匹配该对时,它返回一行,所有列都为空 当没有结果时,有没有办法使函数返回0(零)行 CREATE OR REPLACE FUNCTION find_user_by_credentials(email text, password text) RETURNS "User" AS $$ SELECT * FROM "User" AS "U" WHERE email = "U
CREATE OR REPLACE FUNCTION find_user_by_credentials(email text, password text)
RETURNS
"User"
AS
$$
SELECT *
FROM "User" AS "U"
WHERE email = "U"."Email" AND "U"."Password" = md5(password || "U"."Salt")
;
$$
LANGUAGE SQL IMMUTABLE STRICT;
有趣的是:
如果我将返回类型从“用户”更改为
表格(“Email”文本、“GivenName”文本、“ID”int8、“Password”文本、“Salt”文本)
它按预期工作。
但我真的想用“引用”来表示“用户”,因为维护会更容易
谢谢 这是一个标量函数,因此每次都必须返回值。您可能需要一个SRF函数,设置返回函数:
CREATE OR REPLACE FUNCTION public.foo(boolean)
RETURNS integer
LANGUAGE sql
AS $function$
SELECT * FROM generate_series(1,2) WHERE $1;
$function$
CREATE OR REPLACE FUNCTION public.srf_foo(boolean)
RETURNS SETOF integer
LANGUAGE sql
AS $function$
SELECT * FROM generate_series(1,2) WHERE $1;
$function$
postgres=# \pset null [NULL]
Null display is "[NULL]".
postgres=# SELECT * FROM foo(false);
┌────────┐
│ foo │
╞════════╡
│ [NULL] │
└────────┘
(1 row)
postgres=# SELECT * FROM srf_foo(false);
┌─────────┐
│ srf_foo │
╞═════════╡
└─────────┘
(0 rows)
这可能有点奇怪,因为PostgreSQL区分标量函数和SRF函数,但允许使用SRF作为标量,标量作为SRF(但最好在FROM子句中使用SRF函数,在查询表达式中使用标量函数:
postgres=# SELECT srf_foo(false);
┌─────────┐
│ srf_foo │
╞═════════╡
└─────────┘
(0 rows)
postgres=# SELECT foo(false);
┌────────┐
│ foo │
╞════════╡
│ [NULL] │
└────────┘
(1 row)
您可以看到,SRF功能正在工作:
postgres=# SELECT * FROM srf_foo(true);
┌─────────┐
│ srf_foo │
╞═════════╡
│ 1 │
│ 2 │
└─────────┘
(2 rows)
例如,只需将return子句更改为返回“User”集合您需要将返回类型从“User”更改为“User”集合。如果是单列rowtype,函数将始终生成一行-带值或不带值,而使用SETOF将允许返回由零行或多行组成的集合。我还将函数的语言从SQL更改为PLPGSQL:
CREATE OR REPLACE FUNCTION find_user_by_credentials(email text, password text)
RETURNS SETOF "user" AS $$
DECLARE
user_row RECORD;
BEGIN
SELECT INTO user_row *
FROM "user" AS "U"
WHERE "U".email = "U"."email"
AND "U"."password" = md5("U"."password" || "U"."salt");
IF FOUND THEN
RETURN NEXT user_row;
END IF;
RETURN;
END;
$$
LANGUAGE plpgsql VOLATILE;
请注意-从性能角度来看,对于这些琐碎的功能,使用plpgsql是不好的。由于外部查询的内联,SQL通常会大大加快。其他注意事项-如果必须使用plpgsql-则可以将示例简化为一条语句-`RETURN query。。。