暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Polardb运算符优化应用案例

IT那活儿 2020-09-07
878
[
应用报错
]

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;

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

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论