达梦数据库版本问题导致的一个线上bug记录
摘要:
前段时间公司项目上线,因为服务器,数据库版本等出现了一系列线上问题,本次主要记录国产数据库达梦7和达梦8的版本不同引起的一个
SQL执行报错.
1 问题
order by 关键字与union all 关键字一起使用,由于DM数据库版本问题引起的SQL执行报错.
1.1 具体SQL样式
select * from (
(select 123 num1, 456 num2 from dual order by num1 desc limit 1) UNION ALL
(select 789 num1, 999 num2 from dual order by num1 desc limit 1)
) AS t_all;
1.2 问题重现
图一是达梦8的执行报错信息,但是达梦7却没有报错(图2)
图一生产环境使用的达梦8 图二使用的是达梦7 ,SQL完全一致,但是执行结果一个报错一个没有报错.
唠叨两句:
在网上找了很多资料,逼逼叨叨说了一大堆,什么关键字没有删除等等一系列解决方案,试了都没有卵用…(当然不排除其他人管用,反正我搜的都没有,按照union all 关键字搜都不是我想要的结果…而且不同的文章内容竟然一个字都不差…真的是抄过来连名字都不带改一下的啊!!!)
2 问题解决
既然网上找不到解决方案,就只能一点点摸索,下面是我SQL的"演变"~~~
注意:以下SQL都是再达梦8上执行的,因为达梦7是测试环境的数据库,本来就没有问题.(有的话早也就发现了.)
# 初级阶段 (没报错)
select 123 num1 from dual;
# 第二阶段 (没报错)
select 123 num1, 456 num2 from dual;
# 第三阶段 (没报错)
(select 123 num1, 456 num2 from dual) UNION ALL (select 789 num1, 999 num2 from dual);
# 第四阶段 (没报错)
select * from (
(select 123 num1, 456 num2 from dual ) UNION ALL
(select 789 num1, 999 num2 from dual )
) AS t_all;
# 第五阶段 (报错了!!!)
select * from (
(select 123 num1, 456 num2 from dual order by num1 desc limit 1) UNION ALL
(select 789 num1, 999 num2 from dual order by num1 desc limit 1)
) AS t_all;
执行到第五阶段的SQL其实就已经发现问题了,因为跟第四阶段仅仅是多了一个 order by limit 1 这样一个排序过滤.
那么我很自然就
把生产环境的SQL换成了下面这个样子执行了一次… 结果顺利查询出结果
SELECT t_all.tm timeWithin,t_all.addvcd addvcd FROM
(
( SELECT max(tm) tm, '*****' addvcd FROM iot_bjq_pp_min_r LIMIT 1 ) UNION ALL
( SELECT max(tm) tm, '*****' addvcd FROM iot_xsq_pp_min_r LIMIT 1 )
) AS t_all ORDER BY t_all.tm ASC;
3 总结
可想而知达梦8 和达梦7 版本问题导致的一个问题:
达梦8不支持order by 关键字和 union all 关键字一起使用,达梦7支持.(当然也可能是迁移数据或者设置出现了问题,但是几率很小)
好了ok,就到这里吧.