Sql Oracle与x27之间的差异;s加号(+;)符号和ansi连接符号?

Sql Oracle与x27之间的差异;s加号(+;)符号和ansi连接符号?,sql,performance,oracle,join,Sql,Performance,Oracle,Join,使用oracle的plus符号(+)与ansi标准的join符号有什么区别 性能有差别吗 加号符号是否已被弃用?从Oracle 10(我相信是Oracle 11)开始,加号符号仍然受支持。它的使用被认为是“过时的”,并且不像ANSI JOIN语法那样可移植数据库。它也被认为可读性差得多,尽管如果您来自+背景,熟悉ANSI JOIN可能需要一点时间。在向Oracle抛出brickbats之前需要知道的重要一点是,在ANSI委员会完成连接定义之前,他们已经开发了+语法 没有表现差异;他们在表达同样的

使用oracle的plus符号
(+)
与ansi标准的
join
符号有什么区别

性能有差别吗


加号符号是否已被弃用?

从Oracle 10(我相信是Oracle 11)开始,加号符号仍然受支持。它的使用被认为是“过时的”,并且不像ANSI JOIN语法那样可移植数据库。它也被认为可读性差得多,尽管如果您来自+背景,熟悉ANSI JOIN可能需要一点时间。在向Oracle抛出brickbats之前需要知道的重要一点是,在ANSI委员会完成连接定义之前,他们已经开发了+语法

没有表现差异;他们在表达同样的东西

编辑:如果说“不可移植”,我应该说“仅在Oracle SQL中受支持”

AFAIK,那么
(+)
符号只是为了向后兼容才出现的,因为Oracle在ANSI联接标准出台之前就推出了它。它是特定于Oracle的,当有一个等效的符合标准的版本可用时,您应该避免在新代码中使用它

两者之间似乎存在差异,
(+)
符号具有ANSI连接语法所没有的限制。Oracle本身建议您不要使用
(+)
符号。 完整描述请参见:

Oracle建议您使用
FROM
子句
OUTER JOIN
语法,而不是Oracle JOIN运算符。使用Oracle联接运算符
(+)
的外部联接查询受以下规则和限制的约束,这些规则和限制不适用于
FROM
子句
外部联接
语法:

  • 您不能在也包含来自子句联接语法的
    的查询块中指定
    (+)
    运算符
  • (+)
    运算符只能出现在
    WHERE
    子句中,或者在左相关上下文中(指定
    表格
    子句时)出现在
    FROM
    子句中,并且只能应用于表格或视图的列
  • 如果A和B由多个联接条件联接,则必须在所有这些条件中使用
    (+)
    运算符。如果没有,则Oracle数据库将仅返回简单联接产生的行,但不会出现警告或错误,提示您没有外部联接的结果
  • 如果在外部查询中指定一个表,在内部查询中指定另一个表,则
    (+)
    运算符不会生成外部联接
  • 不能使用
    (+)
    运算符将表外部联接到自身,尽管自联接是有效的
例如,以下语句无效:

SELECT employee_id, manager_id
FROM employees
WHERE employees.manager_id(+) = employees.employee_id;
但是,以下自联接是有效的:

SELECT e1.employee_id, e1.manager_id, e2.employee_id
FROM employees e1, employees e2
WHERE e1.manager_id(+) = e2.employee_id;
  • (+)
    运算符只能应用于列,不能应用于任意表达式。但是,任意表达式可以包含一个或多个标有
    (+)
    运算符的列
  • 其中包含
    (+)
    运算符的
    条件不能使用
    逻辑运算符与其他条件组合
  • 其中
    条件不能使用
    比较条件中的
    将标有
    (+)
    运算符的列与表达式进行比较
如果
WHERE
子句包含将表B中的列与常数进行比较的条件,则必须对该列应用
(+)
运算符,以便Oracle返回表a中已为此列生成空值的行。否则,Oracle只返回简单联接的结果

在执行两对以上表的外部联接的查询中,单个表只能是为另一个表生成的空表。因此,您无法将
(+)
运算符应用于A和B的联接条件中的B列以及B和C的联接条件。有关外部联接的语法,请参阅
选择


我同意Tony Miller的回答,并想补充一点,使用(+)synthax还不能做一些事情:

  • 不能将两个表进行完全外部联接,必须使用两个联接的并集手动进行
  • 不能将表外部联接到两个或多个表,必须手动创建子查询(即:
    b.id=a.id(+)和c.id=a.id(+)
    不是可接受的子句)
Oracle(+)符号仅在Oracle中使用,它是特定于供应商的。而且,ANSI标准连接表示法可以用于任何RDBMS(如Sql Server、MySql等)。否则,Oracle(+)表示法和ANSI标准联接表示法之间没有区别


如果您在Sql查询中使用ANSI标准联接表示法,您可以在任何RDBMS中使用相同的查询。并且,如果您将数据库从Oracle移植到任何其他RDBMS,在这种情况下,您必须使用ANSI语法我使用(+)表示法,因为几乎所有与Oracle Apps r12相关的查询都基于此。在Oracle应用程序查询(甚至是Oracle自己提供的查询)中,我还没有看到一个SQL查询具有标准的“连接”表达式。如果你不相信我,只需谷歌搜索任何与Oracle应用程序相关的信息。例如:

最全面的答案显然是一个接一个的答案

对于那些希望快速转换/映射到ANSI语法的人来说,这是一个补充:

--
-- INNER JOIN
--
SELECT *
FROM EMP e
INNER JOIN DEPT d ON d.DEPTNO = e.DEPTNO;

 -- Synonym in deprecated oracle (+) syntax
SELECT *
FROM EMP e,
     DEPT d
WHERE d.DEPTNO = e.DEPTNO;

--
-- LEFT OUTER JOIN
--
SELECT *
FROM EMP e
LEFT JOIN DEPT d ON d.DEPTNO = e.DEPTNO;

 -- Synonym in deprecated oracle (+) syntax
SELECT *
FROM EMP e,
     DEPT d
WHERE d.DEPTNO (+) = e.DEPTNO;

--
-- RIGHT OUTER JOIN
--
SELECT *
FROM EMP e
RIGHT JOIN DEPT d ON d.DEPTNO = e.DEPTNO;

-- Synonym in deprecated oracle (+) syntax
SELECT *
FROM EMP e,
     DEPT d
WHERE d.DEPTNO = e.DEPTNO(+);

--
-- CROSS JOIN
--
SELECT *
FROM EMP e
CROSS JOIN DEPT d;

 -- Synonym in deprecated oracle (+) syntax
SELECT *
FROM EMP e,
     DEPT d;

--
-- FULL JOIN
--
SELECT *
FROM EMP e
FULL JOIN DEPT d ON d.DEPTNO = e.DEPTNO;

-- Synonym in deprecated oracle (+) syntax !NOT WORKING!
SELECT *
FROM EMP e,
     DEPT d
WHERE d.DEPTNO (+) = e.DEPTNO(+);

使用ANSI语法优于旧的Oracle连接语法的一个很好的理由是,意外创建
SELECT e.last_name,
  d.department_name
FROM employees e,
  departments d
WHERE e.department_id = d.department_id(+);

SELECT e.last_name,
  d.department_name
FROM employees e
LEFT OUTER JOIN departments d
ON (e.department_id = d.department_id);
SELECT e.last_name,
  d.department_name
FROM employees e,
  departments d
WHERE e.department_id(+) = d.department_id;

SELECT e.last_name,
  d.department_name
FROM employees e
RIGHT OUTER JOIN departments d
ON (e.department_id = d.department_id);
SELECT e.last_name,
  d.department_name
FROM employees e,
  departments d
WHERE e.department_id = d.department_id(+)
UNION ALL
SELECT NULL,
  d.department_name
FROM departments d
WHERE NOT EXISTS
  (SELECT 1 FROM employees e WHERE e.department_id = d.department_id
  );

SELECT e.last_name,
  d.department_name
FROM employees e
FULL OUTER JOIN departments d
ON (e.department_id = d.department_id);