org.springframework.jdbc.BadSqlGrammarException:PreparedStatementCallback;
badSQL grammar [SELECT TO_CHAR(TRUNC(SYSDATE,'dd')-TRUNC(op_time,'dd'))overday FROM tb_xxx_xxxx WHERE caseno=? ];
nestedexception is com.aliyun.polardb.util.PSQLException:
ERROR:function to_char(interval) does not exist
Hint:No function matches the given name and argument types. You might needto add explicit type casts.
--直连检查sql报错问题
polardb执行

oracle执行

报错信息需要类型转换,那就转换一下

告知开发侧看能否更改代码解决。
过了一会,开发发来截图,一个模块就有400多,工作量太大,影响进度,看来还得换其他办法。

先看看查询实现原理:
1.trunc后返回类型是timestampwithout time zone

2.两个相减返回值interval类型


3.查看to_char输入和输出返回类型

通过上面3步可以明确知道之前修改新加'DD'实现的逻辑,但是应用侧整改工作量太大,不现实。
既然第3步工作量大,实现不了,那就在第1步或第2步上做做文章。
尝试修理第2步:
减号'-'的左右都是timestampwithout time zone,返回值类型就是interval

到这就明了了,自己定义一个函数timestamp_mi,让他返回值不是interval,而是text就ok啦。
下面开始解决问题:
1.日期格式相减功能实现的sql
SELECT(date_part('epoch',sysdate)-date_part('epoch',sysdate-10))/86400,pg_typeof(date_part('epoch',sysdate)-date_part('epoch',sysdate-10)/86400);

2.创建上面实现功能的sql对应的函数
语法如下:

createor replace function ywjhxt.timestamp_mi (timestamp without time zone,timestamp without time zone) returns double precision as $$
SELECT(date_part('epoch',$1)-date_part('epoch',$2))/86400;
$$language sql;
3.创建新的运算符实现逻辑

createoperator ywjhxt.-(leftarg=timestamp without timezone,rightarg=timestamp without timezone,procedure=ywjhxt.timestamp_mi);


4.检验是否实现功能

5.意外情况处理
奇了怪了,为啥没生效。继续分析,
查看操作符’-’信息:
selectoprname,oprleft::regtype,oprright::regtype,oprresult::regtype,oprcodefrom pg_operator where oprname='-' andoprleft::regtype::text='timestamp without time zone' andoprright::regtype::text='timestamp without time zone';

原来有两个timestampwithout time zone的值进行相减时,有两个实现方式,为啥他选了第一个呢?
尝试去官方文档找答案,还真有。。。

再尝试一下,发现得到了想要的结果,但是这不符合需要啊,还是要改动应用代码。


继续往下翻文档,又有惊喜。

setsearch_path="$user", public,pg_catalog;

至此,问题彻底解决。本次分享到此结束,下次再见。




