PostgreSQL调用自定义函数创建生成列报generation expression not immutable错误
PostgreSQL生成列报错"generation expression is not immutable"解决方法
错误根因
PostgreSQL规定STORED类型的生成列,其计算表达式必须是*IMMUTABLE(不可变)*属性的:即给定相同输入参数时,函数永远返回完全相同的结果,执行过程不能依赖系统时间、其他表数据、会话/数据库配置等会随环境或时间变化的外部因素。
你当前使用的自定义函数ttt.getfunction默认的 volatility 属性为VOLATILE或STABLE,不满足生成列的要求,因此触发报错。
解决步骤
- 第一步:先确认
ttt.getfunction的逻辑是否真的符合不可变要求
若函数计算过程会依赖可变外部因素,无法保证相同输入永远返回相同结果,不要强行修改函数属性,改用触发器实现该字段的自动计算即可。 - 第二步:若函数逻辑确实符合不可变要求,修改函数的volatility属性为
IMMUTABLE
执行如下SQL,注意将语句中的入参类型替换为你定义ttt.getfunction时使用的入参类型,需和actual_sn字段的类型完全匹配:ALTER FUNCTION ttt.getfunction(入参类型) IMMUTABLE; - 第三步:重新执行创建生成列的语句即可
ALTER TABLE ttt.test ADD COLUMN "checkDigit" char GENERATED ALWAYS AS (ttt.getfunction(actual_sn)) STORED;
注意事项
如果你后续修改了ttt.getfunction的内部逻辑,PostgreSQL不会自动同步更新已生成的checkDigit列的值,需要你手动执行全表UPDATE更新该字段,或者删除重建生成列完成数据同步。
内容的提问来源于stack exchange,提问作者siddhartha attri
相关产品推荐
相关产品推荐

