当我执行下面的查询时,我收到以下错误消息:
ORA-00918:栏目明确定义
ORA-02063:来自ABC的前一行
查询:
SELECT
dos.*,
cmd.*,
cmd_r.*,
adr_inc.*,
adr_veh.*,
loc.*,
fou_d.*,
fou_r.*, --Works if I comment this line
mot.*
FROM
DOSSIERS@ABC dos
LEFT JOIN CMDS@ABC cmd ON cmd.DOS_CODE_ID = dos.dos_code_id
LEFT JOIN CMDS_RECCSTR@ABC cmd_r ON cmd_r.DOS_CODE_ID = dos.DOS_CODE_ID AND cmd_r.CMD_CODE_ID = cmd.CMD_CODE_ID AND cmd_r.CMD_DT_CREAT = cmd.CMD_DT_CREAT
LEFT JOIN HISTO_ADR@ABC adr_inc ON adr_inc.DOS_CODE_ID = dos.DOS_CODE_ID
LEFT JOIN HISTO_ADR@ABC adr_veh ON adr_veh.DOS_CODE_ID = dos.DOS_CODE_ID
LEFT JOIN LOC@ABC loc ON dos.DOS_CODE_ID = loc.DOS_CODE_ID
LEFT JOIN FOURNISS@ABC fou_d ON fou_d.PAY_CODE_ID = loc.PAY_CODE_ID_D AND fou_d.FOU_CODE_ID = loc.FOU_CODE_ID_D
LEFT JOIN FOURNISS@ABC fou_r ON fou_r.PAY_CODE_ID = loc.PAY_CODE_ID_R AND fou_r.FOU_CODE_ID = loc.FOU_CODE_ID_R
LEFT JOIN REF_MOT@ABC mot ON mot.RMR_CODE_ID = cmd_r.RMR_CODE_ID
WHERE
dos.REF_EXT = 'XXXXXXX'
如果我在fou_r.*
中对SELECT
发表评论,那就可以了。
以下查询不起作用:
SELECT *
FROM ... ;
SELECT (SELECT count(xxx) FROM ...)
FROM ...;
我在SO上查看了类似的问题,但他们都使用了复杂的查询,或者在SELECT
内使用了很多WHERE
。我很简单就是为什么我不明白什么是错的。
当前数据库: Oracle数据库11g企业版11.2.0.2.0版 - 64位生产
目标数据库(指数据库链接ABC目标): Oracle数据库10g企业版10.2.0.3.0版 - 64位
客户端:Toad for Oracle 9.7.2.5
答案 0 :(得分:1)
你似乎遇到了错误13589271.我无法与MOS分享细节,但无论如何都没有太多分享。它与具有30个字符名称的列的远程表相关,就像在远程FOURNIUSS
表中一样。
不幸的是,只需在查询中对列进行别名,如下所示:
fou_d.COLUMN_WITH_30_CHARACTERS_NAME alias_a,
fou_r.COLUMN_WITH_30_CHARACTERS_NAME alias_b,
...没有帮助,仍然得到相同的错误,因为别名由本地数据库应用,并且问题似乎是在远程访问期间。似乎有用的是使用内联视图在连接之前应用列别名:
...
LEFT JOIN LOC@ABC loc ON dos.DOS_CODE_ID = loc.DOS_CODE_ID
LEFT JOIN (
SELECT PAY_CODE_ID, FOU_CODE_ID, COLUMN_WITH_30_CHARACTERS_NAME alias_a FROM FOURNISS@ABC
) fou_d ON fou_d.PAY_CODE_ID = loc.PAY_CODE_ID_D AND fou_d.FOU_CODE_ID = loc.FOU_CODE_ID_D
LEFT JOIN (
SELECT PAY_CODE_ID, FOU_CODE_ID, COLUMN_WITH_30_CHARACTERS_NAME alias_b FROM FOURNISS@ABC
) fou_r ON fou_r.PAY_CODE_ID = loc.PAY_CODE_ID_R AND fou_r.FOU_CODE_ID = loc.FOU_CODE_ID_R
LEFT JOIN REF_MOT@ABC mot ON mot.RMR_CODE_ID = cmd_r.RMR_CODE_ID
...
如果在两个内联视图中为列提供相同的别名,这甚至可以正常工作。缺点是您必须明确列出表中的所有列(或至少是您感兴趣的列),以便能够将别名应用于有问题的列,但是这样做后您仍然可以使用{ <1}}和fou_d.*
在外部选择列表中。
我没有11.2.0.2数据库但是我已经在11.2.0.3数据库中成功运行了这个数据库,该数据库仍然显示原始代码中的ORA-00918错误。当然,11.2.0.2中的其他内容可能会阻止此解决方法生效。我根本没有看到11.2.0.4中的原始问题,因此升级到该终端补丁版本可能是一个更好的长期解决方案。
无论如何,使用fou_r.*
通常被认为是一种不好的做法,尤其是因为你将从连接中获得大量重复列(例如,每行中有大量*
) ;但是你也可能得到了你真正不想要的其他数据,并且任何消耗这个结果集的东西都必须假设这些表中的列顺序总是相同的 - 任何变化,或者稍后添加或删除专栏,会引起问题。