簡體   English   中英

從 oracle 11g 遷移到 19c 后出現錯誤

[英]error after migration from oracle 11g to 19c

誰能解釋下面的 select 是如何工作的:

select A.B.Column1 Col1
FROM TableA A LEFT JOIN TableB B
ON B.id=A.id;

A.B.Column1是什么意思? 從 oracle 11g 遷移到 19c 后,我的 package 會引發錯誤:

PL/SQL: ORA-00904: "A"."B"."Col1":
         invalid identifier

它也不應該在 11g 中工作,但是 ANSI 語法有時會出現問題 - 特別是在舊版本中 - 你碰巧遇到了一個令人困惑但相當溫和的問題。

在這種情況下,解析器/優化器顯然忽略了可能是但不是對表模式的引用。 這似乎發生在將 ANSI 語法內部轉換為本地 Oracle 語法的過程中。 第一部分是什么並不重要。 您顯示A與另一個表的別名匹配,但這是巧合; 這兩項工作,至少在 11.2.0.2 中,即使Z從未在其他任何地方提及:

select A.B.Column1 Col1
FROM TableA A LEFT JOIN TableB B
ON B.id=A.id;

select Z.B.Column1 Col1
FROM TableA A LEFT JOIN TableB B
ON B.id=A.id;

我已經說過這是一個 ANSI 問題,因為(a)它與您提到的內部連接錯誤,並且(b)它也與老式的外部連接語法錯誤:

select A.B.Column1 Col1
FROM TableA A, TableB B
WHERE B.id = A.id (+);

ORA-00904: "A"."B"."COLUMN1": invalid identifier

SQL 小提琴演示

不必擔心它以前是如何工作的,或者(例如)針對這樣的舊版本提出服務請求。 這是您的舊版本 Oracle 中的錯誤,現在已修復。 不應該起作用,並且由於它 - 正確 - 在 19c 中不起作用,因此您必須通過移除雜散A.來修復它。

SQL 無效。

知道這一點只有兩種可能性:

  1. 11g 同樣引發了錯誤; 或者
  2. 11g 比 19c 具有“更寬松”的容錯性,並假設 A 或 B 並在 output 中應用了選擇。

無論哪種方式,鑒於它是您的 package,解決方案應該相當簡單:

  1. 如果您知道您期望結果來自哪個表,則從別名中刪除不正確的表的引用

  2. 如果 A 有“Column1”而 B 沒有,則刪除“B”。 來自別名

  3. 如果 B 有“Column1”而 A 沒有,則刪除“A”。 來自別名

  4. 如果 A 和 B 都有“Column1”,則找到一個 11g 數據庫並創建一個虛擬查詢,其中 A.id = B.id 且 A.Column1 的值與 B.Column1 不同。 然后運行查詢,如果結果是 A.Column1 值,則刪除“B”。 來自別名,但如果結果是 B.Column1,則刪除“A”。 從別名。

  5. 如果您嘗試實現邏輯“如果 B.Column1 是 null,則返回 A.Column1 的值,否則返回 B.Column1 的值”,然后更正您的 SQL 以讀取如下內容:

    select case
             when B.Column1 is null then
             A.Column1
           else
             B.Column1
           end as Col1
    from TableA A left join TableB B
    on B.id = A.id;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM