我创建了一个函数,理论上应该在成功更改密码时返回true,而在相反的情况下则返回false。
该功能定义为:
CREATE OR REPLACE FUNCTION database."changePassword"(username character varying, newpassword character varying, oldpassword character varying) RETURNS boolean AS
$BODY$
UPDATE database.users SET hash = MD5($2) WHERE (username = $1 AND hash = MD5($3));
SELECT EXISTS(SELECT 1 FROM datsabase.users WHERE username = $1 AND hash = MD5($2))
$BODY$
LANGUAGE sql VOLATILE NOT LEAKPROOF
COST 100;
问题在于,当我调用像SELECT database."changePassword"('usrNm', 'newPassword', 'oldOne');
这样的函数时,首先我得到了预期的真值,并且数据库中的值也发生了变化。
当我再次使用相同的参数调用该函数(并且一次又一次)时,它也返回true,但由于密码现在已更改且通过函数调用发送的旧密码不正确,因此不应该是这种情况。
我做错了吗?
PostgreSQL版本是9.3.1 我从pgAdmin接口调用了函数,从PHP脚本调用了同样的问题。
答案 0 :(得分:2)
如果要返回是否已更改任何密码,可以在plpgsql函数中返回特殊变量FOUND
,如下所示(使用@Pavel的输入进行简化):
CREATE OR REPLACE FUNCTION database."changePassword"(
username character varying
,newpassword character varying
,oldpassword character varying
) RETURNS boolean AS
$func$
BEGIN
UPDATE database.users
SET hash = MD5($2)
WHERE username = $1
AND hash = MD5($3);
RETURN FOUND;
END
$func$
LANGUAGE plpgsql VOLATILE NOT LEAKPROOF;
或者更简单,使用RETURNING
子句。这也适用于普通的sql函数:
CREATE OR REPLACE FUNCTION database."changePassword"(
username character varying
,newpassword character varying
,oldpassword character varying
) RETURNS boolean AS
$func$
UPDATE database.users
SET hash = MD5($2)
WHERE username = $1
AND hash = MD5($3)
RETURNING TRUE;
$func$
LANGUAGE sql VOLATILE NOT LEAKPROOF;
如果没有更新行,则不返回任何内容。否则,你得到TRUE
。
答案 1 :(得分:1)
函数的返回值是SELECT
语句的结果。当存储的用户哈希与第二个参数(newpassword
)的哈希匹配时,结果为真。当密码更改为新密码时,此检查总是成功,并且函数对同一参数返回true,尽管update语句在第二次调用后不更新任何行。您应该更改逻辑,而不是查询匹配的用户和密码,检查天气是否更新了任何行。