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

Posted

技术标签:

【中文标题】ORA-00918: 列定义不明确,使用 DB Link【英文标题】:ORA-00918: column ambigously defined, using DB Link 【发布时间】:2015-09-25 13:24:01 【问题描述】:

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

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

客户: Toad for Oracle 9.7.2.5

【问题讨论】:

谁对这个问题投了反对票,请你给出原因,因为我不确定这个问题有什么问题 我也没有理由不赞成这个问题。而且我看不出错误的任何原因。使用限定符获取数据应该始终有效(只要您不使用 USING,从而从合格列中删除一列)。可能是一个错误。 我很好奇该错误是否仅在使用 db 链接时发生。您是否可以直接在数据库链接ABC 引用的数据库实例上运行相同的查询? fou_r 是远程数据库中的视图吗?这种观点有效吗? 好的,那么如果你的源数据库是 11.2.0.2 它看起来像 bug 13589271; FOURNISS 有一个包含 30 个字符的名称的列吗?您能否添加FOURNISSHISTO_ADR 的定义,看看这是否表明为什么一个有效而另一个无效? 【参考方案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
...

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

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


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

【讨论】:

以上是关于ORA-00918: 列定义不明确,使用 DB Link的主要内容,如果未能解决你的问题,请参考以下文章

不确定为啥会出现 ORA-00918 列定义不明确

ORA-00918: 列定义不明确

Oracle Pivot 和 Pivot XML - ORA-00918:列定义不明确

Oracle Live SQL 中的错误 -> ORA-00918:列定义不明确

ORA-00918: FOR pharmacyschema.sql (RX 药房数据库) 的列定义不明确

ORA-00918: 未明确定义列