Postgres 函数总是返回一行

Dan*_*ilo 3 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"."Email" AND "U"."Password" = md5(password || "U"."Salt")
    ;
$$
LANGUAGE SQL IMMUTABLE STRICT;
Run Code Online (Sandbox Code Playgroud)

有趣:如果我将返回类型从“用户”更改为 TABLE("Email" text,"GivenName" text,"ID" int8, "Password" text,"Salt" text)

它按预期工作。但我真的想对“用户”使用“引用”,因为维护会更容易。

谢谢!

Pav*_*ule 7

这是一个标量函数,因此每次都必须返回值。您可能需要一个 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)
Run Code Online (Sandbox Code Playgroud)

这可能有点奇怪,因为 PostgreSQL 区分标量函数和 SRF 函数,但允许将 SRF 用作标量,将标量用作 SRF(但最好在 FROM 子句中使用 SRF 函数,在查询表达式中使用标量函数:

postgres=# SELECT srf_foo(false);
???????????
? srf_foo ?
???????????
???????????
(0 rows)

postgres=# SELECT foo(false);
??????????
?  foo   ?
??????????
? [NULL] ?
??????????
(1 row)
Run Code Online (Sandbox Code Playgroud)

您可以看到,SRF 功能正在运行:

postgres=# SELECT * FROM srf_foo(true);
???????????
? srf_foo ?
???????????
?       1 ?
?       2 ?
???????????
(2 rows)
Run Code Online (Sandbox Code Playgroud)

对于您的示例 - 只需将 return 子句更改为 RETURNS SETOF "User"