函数未返回预期值

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 函数在本地提供时未返回预期的环境配置

Azure 函数对象返回未返回正确的嵌套值

Firebase 云函数错误:函数返回未定义、预期的 Promise 或值

函数以状态完成:'ok',但控制台日志显示函数返回未定义、预期的 Promise 或值

Firebase 云函数 - 返回未定义、预期的 Promise 或值

Javascript函数返回未定义,预期整数值[重复]