Postgresql函数波动率类别

时间:2016-02-09 07:10:40

标签: sql postgresql

我对波动率类别感到有点困惑。 我阅读了页面here

我了解IMMUTABLE是什么,但我真的不明白何时使用VOLATILESTABLE

假设这是我的功能:

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表的状态。

1 个答案:

答案 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()返回当前语句的开始时间。

该函数显然不能是不可变的,因为它在两个连续的语句中返回不同的值。