是否有关于使用显式 ANSI JOIN 与隐式连接的 Oracle 官方建议?
Posted
技术标签:
【中文标题】是否有关于使用显式 ANSI JOIN 与隐式连接的 Oracle 官方建议?【英文标题】:Is there an Oracle official recommendation on the use of explicit ANSI JOINs vs implicit joins? 【发布时间】:2011-12-10 06:20:34 【问题描述】:注意:我并不是要您告诉我“使用显式联接”,而是要查找有关该主题的 Oracle 官方职位。
From Oracle database documentation(也出现在 9i 和 11g 文档中):
Oracle 建议您使用
FROM
子句OUTER JOIN
语法 而不是 Oracle 连接运算符。使用 Oracle 连接运算符(+)
受以下规则和 限制 […]
换句话说,Oracle 建议首选这两种形式中的第一种:
FROM a LEFT JOIN b ON b.x = a.x
vs
FROM a, b WHERE b.x(+) = a.x
但是,我从未在任何 Oracle 文档中找到一个建议最好使用这两种形式中的一种:
FROM a INNER JOIN b ON b.x = a.x
vs
FROM a, b WHERE b.x = a.x
有没有漏掉的段落?
【问题讨论】:
这是一个有趣的问题,假设您从here 得到了引用,那么所有直接在此建议上方的“内连接”示例都使用 where 子句连接!这似乎与只推荐外部连接并创建连接类型的二分法相矛盾。 【参考方案1】:Oracle 支持网站上有许多关于 ANSI 连接语法问题的注释,以及建议使用 oracle 语法的变通方法。
错误 5188321 错误结果(无行)或来自 ANSI 外连接的 ORA-1445
Versions affected: Versions >= 9.2.0.1 but < 11
Description
Wrong results or an ORA-1445 can be returned with a query involving a
very large select list count when ANSI OUTER JOIN syntax is used.
Workaround
Use native oracle outer join syntax
or
reduce the select list count.
错误 5368296 ANSI 连接 SQL 可能不会针对不明确的列报告 ORA-918
Versions affected: Versions < 11
Description
****
Note: This fix introduces the problem described in bug 7318276
One off fixes for that bug address the issue here also.
****
ORA-918 is not reported for an ambiguous column in a query
involving an ANSI join of more than 2 tables/objects.
eg:
-- 2 table join, returns ORA-918
SELECT empno
FROM emp a JOIN emp b on a.empno = b.empno;
-- 3 table join does not report ORA-918 when it should ...
SELECT empno
FROM emp a JOIN emp b on a.empno = b.empno
JOIN emp c on a.empno = c.empno;
错误 7670135 编译 ANSI 连接的解析时间过长
Versions affected: Versions BELOW 11.2
Description
A query having ANSI join(s) may take noticeable time during query compilation,
especially if the query includes an NVL() function.
Workaround:
Use ORACLE join instead of ANSI join
来自 Oracle Press - Oracle OCP 11g all in one 考试指南
还有来自 asktom(谁是不承诺的)
Historically there have been bugs related to ANSI syntax, in fact even the
10.2.0.4 projected issues list includes 10 bugs/issues related to ANSI syntax.
In the past I've encountered some of these bugs myself, and have continued to use
and advocate the "traditional" Oracle style.
I'd like to know if you feel that the implementation of ANSI syntax is now equally
robust compared to the traditional syntax.
Followup February 19, 2008 - 5pm Central time zone:
unfortunately, there are bugs in non-ansi joins too, probably more than 10 in fact.
I personally do not use the new syntax (except in the rare case of a full outer join,
a truly rare beast to encounter). I have no comment on it really.
另请参阅有关同一主题的先前问题 Difference between Oracle's plus (+) notation and ansi JOIN notation?
我还在document 中找到了这个声明,但没有提及它的来源
“从 Oracle 9i 开始,Oracle 建议 SQL 开发人员使用 ANSI 连接语法而不是 Oracle 专有 (+) 语法。这个建议有几个原因,包括:
• 更易于隔离和读取(不会混淆连接代码和限制代码) • 更容易正确地构造连接代码(尤其是在“外部”连接的情况下) • 可移植语法适用于所有其他符合 ANSI 的数据库,例如 MS SQL Server、DB2、mysql、PostgreSQL 等 • 由于它是普遍接受的标准,因此它是所有未来数据库和第三方供应商工具的通用目标 • 专有的 Oracle 外连接 (+) 语法一次只能在一个方向上使用,它不能执行完全外连接 • 加上 Oracle 文档中的这些额外限制: o (+) 运算符只能应用于列,不能应用于任意表达式。但是,任意表达式可以包含一个或多个标有 (+) 运算符的列。 o 包含 (+) 运算符的条件不能与使用 OR 逻辑运算符的另一个条件组合。 o 条件不能使用 IN 比较条件将标有 (+) 运算符的列与表达式进行比较。 o 条件不能将任何标有 (+) 运算符的列与子查询进行比较。"
因此,是时候采用 ANSI 连接语法了——并进入 21 世纪
【讨论】:
谢谢。从您的链接中我还发现了这个:hoopercharles.wordpress.com/2010/12/26/…【参考方案2】:如果有的话,我还没有看到。特别是外连接首选 ANSI 语法(除了非标准的、Oracle 特定的(+)
符号)的原因是更多的外连接可以使用 ANSI 语法来表达。限制“ORA-01417:一个表最多可以外连接到另一个表”适用于(+)
外连接,但不适用于 ANSI 外连接。其他不适用于 ANSI 外连接的 (+)
限制是 documented here。
一位备受尊敬的 Oracle 专家实际上建议坚持内部连接的旧语法 - 请参阅 Jonathan Lewis's blog。他在那里说,无论如何,ANSI 连接都被转换为传统的 Oracle 连接。我不 100% 同意他的观点(我更喜欢 ANSI 加入我自己),但不会声称在该主题上只掌握他的一小部分知识。
简而言之,ANSI 外连接在技术上优于旧的 (+)
连接,而内连接则更多地只是样式问题。
【讨论】:
感谢您的回答。什么都没看到并不代表什么都没有,所以如果一段时间后没有其他人找到官方推荐,我会接受答案。以上是关于是否有关于使用显式 ANSI JOIN 与隐式连接的 Oracle 官方建议?的主要内容,如果未能解决你的问题,请参考以下文章
何时在 Selenium Webdriver 中使用显式等待与隐式等待?