ORA-00918:定义不明确的列,使用DB Link



当我执行下面的查询时,我得到以下错误消息:

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'

如果我在SELECT中注释fou_r.*,它可以工作。

下面的查询也不起作用:

SELECT *
FROM ... ;
SELECT (SELECT count(xxx) FROM ...)
FROM ...;

我在SO上看到了类似的问题,但他们都使用复杂的查询或在WHERE中使用许多SELECT。我的很简单,这就是为什么我不明白哪里出了问题。

当前数据库: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production

目标数据库(指db link ABC目标数据库): Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi

客户:

蟾蜍对甲骨文9.7.2.5

您似乎正在击中bug 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
...

如果您在两个内联视图中为列提供相同的别名,这甚至可以工作。缺点是您必须显式列出表中的所有列(或至少是您感兴趣的列),以便能够将别名应用于有问题的列,但是这样做之后,您仍然可以在外部选择列表中使用fou_d.*fou_r.*

我没有11.2.0.2数据库,但我已经在11.2.0.3数据库中成功运行了这个数据库,该数据库仍然显示了原始代码中的ORA-00918错误。当然,11.2.0.2中的其他内容可能会阻止此解决方案的有效性。我在11.2.0.4中根本没有看到原来的问题,所以升级到那个终端补丁版本可能是一个更好的长期解决方案。


使用*通常被认为是一种不好的做法,尤其是因为你将从连接中获得很多重复的列(例如,每行中有很多dos_code_id);但是您也可能会得到其他您并不真正想要的数据,并且任何使用此结果集的东西都必须假设这些表中的列顺序始终相同—任何变化,或者后来添加或删除列,都将导致问题。

相关内容

  • 没有找到相关文章

最新更新