PostgreSQL:更新函数返回布尔值

ma1*_*w28 4 postgresql boolean sql-update sql-returning

功能是否良好?

CREATE FUNCTION password_set(bigint, char) RETURNS boolean AS $$
   UPDATE users SET password = $2 WHERE id = $1 RETURNING TRUE;
$$ LANGUAGE SQL;
Run Code Online (Sandbox Code Playgroud)

TRUEUPDATE设置时返回password但是NULL(而不是FALSE)何时UPDATE未设置password.

我认为这将适用于所有意图和目的,但你认为这没关系吗?

如果没有,你怎么会改变返回功能FALSE(而不是NULL),如果UPDATE没有设置password

Erw*_*ter 10

首先,你希望使用的数据类型char.这是传递"密码"文本的同义词,character(1)也是完全错误的.任何字符串都将被截断为第一个字符.每个文件:

该符号varchar(n)char(n)是别名character varying(n)character(n)分别.character没有长度说明符相当于character(1).

接下来,有什么不对的函数返回TRUENULL

如果您确实需要 TRUE/FALSE返回,您使用数据修改CTE的想法是有效的.但是,该代码具有误导性.你让它看起来像TRUE在最后的SELECT会很重要,但它不会:

CREATE FUNCTION password_set(bigint, text)
  RETURNS boolean AS
$func$
   WITH u AS (UPDATE users SET password = $2 WHERE id = $1 RETURNING 1)
   SELECT EXISTS (SELECT * FROM u)
$func$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)

EXISTS仅考虑是否返回一行.无论你写这无关紧要NULLFALSETRUE*'foo'或什么的.返回的函数TRUE只告诉我们,UPDATE返回的一行或多行.

替代方案是使用特殊变量PL/pgSQL函数:FOUND

CREATE OR REPLACE FUNCTION password_set(bigint, text)
  RETURNS boolean AS
$func$
BEGIN
   UPDATE users SET password = $2 WHERE id = $1;

   IF FOUND THEN
      RETURN TRUE;
   ELSE
      RETURN FALSE;
   END IF;
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

更快一些,可能更清晰.或者,正如@pozs评论的那样,因为我们boolean在这种情况下仍然会返回,只需:

   RETURN FOUND;
Run Code Online (Sandbox Code Playgroud)

  • 也许`RETURN FOUND`会更清晰,因为`FOUND`已经是一个`BOOLEAN`*变量*. (3认同)