PostgreSQL:更新函数返回布尔值

时间:2014-04-14 22:29:12

标签: postgresql sql-update boolean sql-returning

功能是否良好?

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

TRUE设置UPDATEpassword(而不是NULLFALSE未设置{时{}返回UPDATE {1}}。

我认为这样可以用于所有意图和目的,但你觉得这样可以吗?

如果没有,如果password没有设置FALSE,您将如何更改函数以返回NULL(而不是UPDATE)?

2 个答案:

答案 0 :(得分:9)

首先,您想要使用数据类型 char 。这是传递“密码”文本的character(1)完全错误的同义词。任何字符串都将被截断为第一个字符。 Per documentation:

  

符号varchar(n) char(n) 分别是character varying(n)character(n)的别名。 character没有长度   说明符等同于 character(1)

接下来,返回TRUENULL的函数出了什么问题?

如果您确实需要 TRUE / FALSE,则使用data-modifying CTE的想法有效。但是,该代码具有误导性。你觉得最终SELECT中的TRUE看起来很重要,但事实并非如此:

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;

EXISTS仅考虑是否返回一行。您是否撰写NULLFALSETRUE*'foo'或其他内容无关紧要。返回TRUE的函数只告诉我们,UPDATE返回了一行或多行。

使用special variable FOUND

替代将是 PL / pgSQL 函数:

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;

快一点,可能更清晰。或者,as @pozs commented,因为在这种情况下我们仍然会返回boolean,只需:

   RETURN FOUND;

答案 1 :(得分:1)

如果您只是在SETOF之前添加boolean,那么该函数将返回0行,而不是带有NULL单元格的1行。

否则,您可以尝试:

CREATE FUNCTION password_set(bigint, char) RETURNS boolean AS $$
   WITH u AS (UPDATE users SET password = $2 WHERE id = $1 RETURNING TRUE)
   SELECT EXISTS (SELECT TRUE FROM u);
$$ LANGUAGE SQL;