PostgreSQL 9.2两库执行now()+8报运算符不存在错误求助
解决PostgreSQL 9.2中
now()+8在部分数据库报错的问题 首先咱们直击核心:你遇到的Operator does not exist: timestamp with time zone + integer错误,本质是PostgreSQL默认没有定义timestamptz(timestamp with time zone)和integer直接相加的运算符。那为什么其中一个数据库能正常跑?大概率是这个库存在自定义运算符或者隐式类型转换规则,而另一个库缺失这些配置。
下面一步步排查并解决问题:
1. 先查差异:定位问题根源
分别在两个数据库执行以下查询,找出具体差异:
检查是否存在timestamptz + integer的自定义运算符
SELECT oprname, oprleft::regtype, oprright::regtype, oprcode::regproc FROM pg_operator WHERE oprname = '+' AND oprleft = 'timestamp with time zone'::regtype AND oprright = 'integer'::regtype;
- 如果能正常运行的库返回结果,报错的库没有,说明前者有自定义的
+运算符,你需要把这个运算符复制到报错的库中。
检查是否存在integer到interval的隐式转换
另一种可能是能运行的库允许integer自动转为interval(比如把8默认识别为8 days),执行以下查询:
SELECT castsource::regtype, casttarget::regtype, castcontext FROM pg_cast WHERE castsource = 'integer'::regtype AND casttarget = 'interval'::regtype;
castcontext字段为'i'表示这是隐式转换。如果能运行的库有这条记录,报错的库没有,那就是隐式转换规则的差异。
2. 快速兼容:创建自定义运算符适配现有代码
假设你的业务中now()+8是指当前时间加8天(如果是小时/分钟,只需修改下面的转换逻辑),可以在报错的数据库中创建自定义运算符和配套函数,直接兼容现有近1000个函数的写法:
步骤1:创建转换函数
CREATE OR REPLACE FUNCTION timestamptz_plus_integer( input_time timestamp with time zone, add_days integer ) RETURNS timestamp with time zone AS $$ BEGIN -- 把整数转为"X days"格式的interval,再和时间相加 RETURN input_time + (add_days || ' days')::interval; END; $$ LANGUAGE plpgsql IMMUTABLE;
步骤2:创建timestamptz + integer运算符
CREATE OPERATOR + ( LEFTARG = timestamp with time zone, RIGHTARG = integer, PROCEDURE = timestamptz_plus_integer, COMMUTATOR = +, NEGATOR = - );
执行完这两步后,now()+8就能在报错的库中正常运行,逻辑和now() + interval '8 day'完全一致。
3. 额外提醒
- 不建议直接添加
integer到interval的隐式转换——这可能会引发其他类型匹配的冲突,创建自定义运算符是更安全的方案。 - 另外要注意:PostgreSQL 9.2早已停止官方支持(终止于2017年),存在安全风险,后续建议尽快升级到更高版本。
内容的提问来源于stack exchange,提问作者sanoop
相关产品推荐
相关产品推荐

