1

以下のクエリを実行すると、次のエラー メッセージが表示されます。

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 Database 11g Enterprise Edition リリース 11.2.0.2.0 - 64 ビット製品

ターゲット データベース (db リンク ABC ターゲットを参照): Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi

クライアント: Toad for Oracle 9.7.2.5

4

1 に答える 1

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
...

これは、両方のインライン ビューで列に同じエイリアスを指定した場合でも機能します。欠点は、エイリアスを問題のあるものに適用できるようにするために、テーブルのすべての列 (または少なくとも関心のある列) を明示的にリストする必要があることですが、そうしても引き続き使用できfou_d.*fou_r.*外側の選択リストで。

私は11.2.0.2データベースを持っていませんが、元のコードからまだORA-00918エラーを示していた11.2.0.3データベースでこれを正常に実行しました。もちろん、11.2.0.2 の他の何かがこの回避策の効果を妨げる可能性があります。11.2.0.4 の元の問題はまったく見られないため、そのターミナル パッチ リリースにアップグレードすることが長期的な解決策になる可能性があります。


とにかく、使用する*ことは一般的に悪い習慣と見なされます。特に、結合から多くの重複した列を取得するためです (dos_code_idたとえば、各行に多くの列があります)。ただし、実際には必要のない他のデータも取得する可能性が高く、この結果セットを使用するものはすべて、これらのテーブルで列の順序が常に同じであると想定する必要があります。列、問題が発生します。

于 2015-09-25T15:37:54.453 に答える