函数未返回预期值
Posted
技术标签:
【中文标题】函数未返回预期值【英文标题】:Function not returning expected values 【发布时间】:2013-12-23 21:45:15 【问题描述】:我创建了一个函数,理论上应该在密码更改成功时返回 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,并且数据库中的值发生了变化。
当我使用相同的参数再次(一次又一次)调用该函数时,它也返回 true,但由于密码现在已更改,并且通过函数调用发送的旧密码不正确,因此不应出现这种情况。
我做错了吗?
PostgreSQL 版本是 9.3.1。 我已经从 pgAdmin 界面和 php 脚本调用了该函数,同样的问题。
【问题讨论】:
【参考方案1】:如果您想返回密码是否被更改,您可以在这样的 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
。
【讨论】:
“FOUND”变量是布尔值,因此您可以简化代码 - 只需使用“RETURN FOUND” @PavelStehule:当然!我通常不会错过这样一个简化的好机会。应用了。【参考方案2】:函数的返回值是SELECT
语句的结果。当存储的用户哈希与第二个参数(newpassword
)的哈希匹配时,结果为真。当密码更改为新密码时,此检查始终成功,并且该函数对同一参数返回 true,尽管 update 语句在第二次调用后没有更新任何行。您应该更改您的逻辑,而不是查询匹配的用户和密码,而是检查天气是否更新了任何行。
【讨论】:
以上是关于函数未返回预期值的主要内容,如果未能解决你的问题,请参考以下文章
Firebase 云函数错误:函数返回未定义、预期的 Promise 或值
函数以状态完成:'ok',但控制台日志显示函数返回未定义、预期的 Promise 或值