我们写了一个函数get_timestamp()
定义为
CREATE OR REPLACE FUNCTION get_timestamp()
RETURNS integer AS
$$
SELECT (FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 10) - 13885344000)::int;
$$
LANGUAGE SQL;
这用于 INSERT 和 UPDATE 以在数据库记录的创建和修改字段中输入或编辑值。但是,我们发现在连续添加或更新记录时它返回相同的值。
在检查 pgAdmin III 中的函数时,我们注意到在运行 SQL 来构建函数时,关键字 IMMUTABLE 已在 LANGUAGE SQL 语句之后注入。文档声明默认为 VOLATILE (如果这些都没有出现,则 VOLATILE 是默认假设)所以我不确定为什么要注入 IMMUTABLE,但是,将其更改为 STABLE 已经解决了重复值的问题。
注意:正如接受的答案中所述, pgAdmin 或 Postgres 永远不会将 IMMUTABLE 添加到函数中,并且必须在开发过程中添加。
我猜正在发生的事情是正在评估此函数并且正在缓存结果以进行优化,因为它被标记为 IMMUTABLE 指示 Postgres 引擎在给定相同(空)参数列表的情况下返回值不应更改。但是,当不在触发器中使用时,当直接在 INSERT 语句中使用时,该函数将返回一个不同的值五次,然后从那时起返回相同的值。这是由于某些优化算法说“如果在会话中使用 IMMUTABLE 函数超过 5 次,则缓存结果以供将来调用”之类的内容吗?
任何关于如何在 Postgres 函数中使用这些关键字的说明将不胜感激。鉴于我们在触发器中使用此功能,STABLE 对我们来说是正确的选择,还是有更多需要考虑的事情,例如文档说:
(对于希望查询当前命令修改的行的 AFTER 触发器是不合适的。)
但我并不完全清楚为什么。