postgresql - 如何确保存储函数始终返回 TRUE 或 FALSE?

标签 postgresql stored-procedures plpgsql coalesce postgresql-9.5

我想使用以下存储函数来验证用户数据:

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() 调用...但是是否有更好的方法来解决这个问题?

最佳答案

检查 is [not] distinct from

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/

相关文章:

sql - 如何每天自动运行一个存储过程

sql - 在存储过程中嵌入html代码

sql - 返回数据立方体的 PostgreSQL 函数

PostgreSQL GOTO like 关键字跳转到一个 block

sql - 使用 GroupBy 从多对多中选择

sql - 运算符不存在 : timestamp without time zone ~~* unknown ruby code

sql-server - 从 SSIS 运行时,存储过程返回架构版本更改错误,但直接运行时则不会

PostgreSQL 9.3 触发器函数插入到具有参数化名称的表中

全部匹配或全不匹配的 SQL

postgresql - 为具有多种元素种类的库存控制系统建模