我对波动率类别感到有点困惑。 我阅读了页面here
我了解IMMUTABLE
是什么,但我真的不明白何时使用VOLATILE
和STABLE
假设这是我的功能:
CREATE OR REPLACE FUNCTION sales.isallowed(userid integer)
RETURNS boolean AS
$BODY$
select exists(select id from permmisions where userid=userid);
$BODY$
LANGUAGE sql VOLATILE
COST 100;
应该是VOLATILE
还是STABLE
?
一方面它没有副作用,另一方面我的系统与很多用户同时工作...
假设userid = 100运行此函数,结果为true。
然后其他人从权限表中删除了userid = 100的行。
然后userid = 100再次运行此功能。现在结果应该是假的,这意味着它已被更改。 STABLE
会好吗?
真正令我困惑的是指南中的这句话:
STABLE函数无法修改数据库,可以保证 返回相同的结果
在我的情况下,结果不一样..结果是基于permmison表的状态。
答案 0 :(得分:2)
如果您对该函数是否应归类为volatile或stable有疑问,请考虑在单个语句中多次使用该函数。如果函数有可能在一个语句中为相同的参数返回不同的值,则它可能不稳定(当然也不可变)。
你的函数应该是易变的,因为你可以用相同的参数得到不同的结果,例如:
with q1 as (
select isallowed(1) res
),
q2 as (
delete from permisions
where id = 1
returning id
)
select
id, res, isallowed(1)
from q1
cross join q2;
id | res | isallowed
----+-----+-----------
1 | t | f
(1 row)
请注意,将挥发性功能错误分类为稳定可能会导致错误结果,而相反的错误只会导致性能下降。如果没有确定性,将函数定义为volatile是更安全的。
函数statement_timestamp()
可以是稳定函数的完美示例。每the documentation:
statement_timestamp()返回当前语句的开始时间。
该函数显然不能是不可变的,因为它在两个连续的语句中返回不同的值。