Oracle版本不同导致子查询表名相同时,查询失败
一、分析思路
环境:ssm项目+oracle数据库
由于疫情,居家办公,发现公司的项目弄到自己的电脑之后,应该是能正常跑的通才对,按照故事剧情,不出意外的话就要出意外了,请看下面
看到这个界面我直接原地起飞。
代码运行异常,后来通过排查确定原因是因为SQL语句执行失败。
未明确定义列,嗯?????
这个代码在公司电脑上命名跑的好好的,在自己电脑就运行异常
接下来就是将SQL复制到Navicat中去运行,其实这个sql远没有这么简单,这是后来经过层层排查,把这段SQL简化简化再简化成了这样
SELECT
A.REP_ID,
A.REP_DATE,
A.SUBMIT_ORG_ID,
A.REP_STATUS_ID,
DECODE(CW.REP_STATUS_ID, NULL, '待签收', 3, '已签收') CW_STATUS,
CW.OPERATE_TIME CW_TIME
FROM
(
(
SELECT
REP_ID,
REP_DATE,
SUBMIT_ORG_ID,
MAX( TO_NUMBER( REP_STATUS_ID ) ) REP_STATUS_ID
FROM REP_STATUS
WHERE REP_ID = '00002'
AND REP_STATUS_ID IN ( '1', '2', '5', '10' )
AND REP_DATE LIKE '%2022-06%'
GROUP BY
REP_ID,
REP_DATE,
SUBMIT_ORG_ID
) A
LEFT OUTER JOIN (
SELECT REP_DATE, SUBMIT_ORG_ID, REP_STATUS_ID FROM REP_STATUS WHERE REP_ID = '00002' AND REP_STATUS_ID = '3' AND CHECK_DEPT_ID = '11006000'
) CW ON CW.SUBMIT_ORG_ID = A.SUBMIT_ORG_ID
LEFT OUTER JOIN REP_STATUS CW ON A.REP_ID = CW.REP_ID
AND A.REP_DATE = CW.REP_DATE
AND A.SUBMIT_ORG_ID = CW.SUBMIT_ORG_ID
AND CW.REP_STATUS_ID = '3'
AND CW.CHECK_DEPT_ID = '11006000'
)
这是我自己的电脑执行, 好的漂亮,出错了提示 未明确定义列
相同的sql,到公司的电脑去执行
有点模糊,反正就是能查询出来结果,这时候我就有疑问了,这是怎么回事
这里解释一下,我把查询的逻辑关系梳理了一下,其实就是在查询的时候做了三个临时表分别是
表A,表CW,表CW
这里就出现问题了,其中有两张临时表的表名都是CW,这样导致查询列不明确。
但是这个SQL在公司的电脑上却没有问题
想了一下会不会是因为Oracle的版本不同导致了这个问题呢
查了一下自己的电脑的Oracle版本和公司的版本有什么不同
自己的Oracle版本:
公司的Oracle版本:
继续思考,首先两个临时表CW,推断出应该是高版本的Oracle自动的识别除了列字段,因为第一个临时CW表,是没有 OPERATE_TIME 字段的,所以它会自动的匹配第二个表中的数据。
二、解决办法
其实问题也非常好解决,只要两个临时表的名称不重复就好了,比如说把第二个临时表名称改为CW1,这样就能正常执行了,这也算是踩坑吧
SELECT
A.REP_ID,
A.REP_DATE,
A.SUBMIT_ORG_ID,
A.REP_STATUS_ID,
DECODE(CW.REP_STATUS_ID, NULL, '待签收', 3, '已签收') CW_STATUS,
CW.OPERATE_TIME CW_TIME
FROM
(
(
SELECT
REP_ID,
REP_DATE,
SUBMIT_ORG_ID,
MAX( TO_NUMBER( REP_STATUS_ID ) ) REP_STATUS_ID
FROM REP_STATUS
WHERE REP_ID = '00002'
AND REP_STATUS_ID IN ( '1', '2', '5', '10' )
AND REP_DATE LIKE '%2022-06%'
GROUP BY
REP_ID,
REP_DATE,
SUBMIT_ORG_ID
) A
LEFT OUTER JOIN (
SELECT REP_DATE, SUBMIT_ORG_ID, REP_STATUS_ID FROM REP_STATUS WHERE REP_ID = '00002' AND REP_STATUS_ID = '3' AND CHECK_DEPT_ID = '11006000'
) CW1 ON CW1.SUBMIT_ORG_ID = A.SUBMIT_ORG_ID
LEFT OUTER JOIN REP_STATUS CW ON A.REP_ID = CW.REP_ID
AND A.REP_DATE = CW.REP_DATE
AND A.SUBMIT_ORG_ID = CW.SUBMIT_ORG_ID
AND CW.REP_STATUS_ID = '3'
AND CW.CHECK_DEPT_ID = '11006000'
)
将第一个临时表名称换了一下就可以了。
CSDN-Ada助手: 云原生入门 技能树或许可以帮到你:https://edu.csdn.net/skill/cloud_native?utm_source=AI_act_cloud_native