繁体   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