我想使用以下存储函数来验证用户数据:
CREATE OR REPLACE FUNCTION check_user(
in_social integer,
in_sid varchar(255),
in_auth varchar(32))
RETURNS boolean AS
$func$
SELECT MD5('secret word' || in_social || in_sid) = in_auth;
$func$ LANGUAGE sql IMMUTABLE;
我将在另一个存储函数中循环遍历 JSON 对象数组时调用它 - 如果它为任何 JSON 对象返回 FALSE
,将 RAISE EXCEPTION
(从而回滚整个事务)。
我没有在这里转储我的第二个存储函数的源代码,而是在下面准备了 3 个简单的测试函数 -
CREATE OR REPLACE FUNCTION test1() RETURNS void AS
$func$
BEGIN
IF NOT check_user(42, 'user1', '56db1046fa7b664c9b3d05bf7413552a') THEN
RAISE NOTICE 'invalid user';
ELSE
RAISE NOTICE 'valid user';
END IF;
END
$func$ LANGUAGE plpgsql;
第一个函数按预期工作并打印 valid user
。
CREATE OR REPLACE FUNCTION test2() RETURNS void AS
$func$
BEGIN
IF NOT check_user(42, 'user2', '56db1046fa7b664c9b3d05bf7413552a') THEN
RAISE NOTICE 'invalid user';
ELSE
RAISE NOTICE 'valid user';
END IF;
END
$func$ LANGUAGE plpgsql;
第二个函数按预期工作并打印invalid user
。
CREATE OR REPLACE FUNCTION test3() RETURNS void AS
$func$
BEGIN
IF NOT check_user(42, 'user1', NULL) THEN
RAISE NOTICE 'invalid user';
ELSE
RAISE NOTICE 'valid user';
END IF;
END
$func$ LANGUAGE plpgsql;
第三个函数没有按预期工作并打印valid user
。
发生这种情况是因为 check_user()
返回 NULL
而不是 bool 值。
COALESCE
可以包含在 IF
语句中的 check_user()
调用...但是是否有更好的方法来解决这个问题?
最佳答案
select md5('secret word' || in_social || in_sid) is not distinct from in_auth;
但是请注意,如果双方都评估为 null
,则比较将返回 true
:
For non-null inputs, IS DISTINCT FROM is the same as the <> operator. However, if both inputs are null it returns false, and if only one input is null it returns true. Similarly, IS NOT DISTINCT FROM is identical to = for non-null inputs, but it returns true when both inputs are null, and false when only one input is null. Thus, these constructs effectively act as though null were a normal data value, rather than "unknown".
更简单的是只声明函数 strict
并将返回值与 is not true
进行比较:
if check_user(42, 'user1', null) is not true then raise notice 'invalid user';
STRICT indicates that the function always returns null whenever any of its arguments are null. If this parameter is specified, the function is not executed when there are null arguments; instead a null result is assumed automatically.
这有一个额外的好处,可以避免执行函数的任何成本。
关于postgresql - 如何确保存储函数始终返回 TRUE 或 FALSE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35742865/