功能是否良好?
CREATE FUNCTION password_set(bigint, char) RETURNS boolean AS $$
UPDATE users SET password = $2 WHERE id = $1 RETURNING TRUE;
$$ LANGUAGE SQL;
当TRUE
设置UPDATE
而password
(而不是NULL
)FALSE
未设置{时{}返回UPDATE
{1}}。
我认为这样可以用于所有意图和目的,但你觉得这样可以吗?
如果没有,如果password
没有设置FALSE
,您将如何更改函数以返回NULL
(而不是UPDATE
)?
答案 0 :(得分:9)
首先,您不想要使用数据类型 。这是传递“密码”文本的char
character(1)
和完全错误的同义词。任何字符串都将被截断为第一个字符。 Per documentation:
符号
varchar(n)
和char(n)
分别是character varying(n)
和character(n)
的别名。character
没有长度 说明符等同于character(1)
。
接下来,返回TRUE
或NULL
的函数出了什么问题?
如果您确实需要 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
仅考虑是否返回一行。您是否撰写NULL
或FALSE
或TRUE
或*
或'foo'
或其他内容无关紧要。返回TRUE
的函数只告诉我们,UPDATE
返回了一行或多行。
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;