Quelle est la différence entre l'utilisation de la notation plus d'Oracle (+)
sur la norme ansi join
notation?
Y a-t-il une différence de performances?
La notation plus est-elle déconseillée?
AFAIK, la notation (+)
N'est présente que pour la compatibilité ascendante car Oracle a fait ses débuts avant la mise en place de la norme ANSI pour les jointures. Il est spécifique à Oracle et vous devez éviter de l'utiliser dans le nouveau code lorsqu'une version équivalente conforme aux normes est disponible.
Il semble qu'il y ait des différences entre les deux, et la notation (+)
A des restrictions que la syntaxe de jointure ANSI n'a pas. Oracle recommande lui-même de ne pas utiliser la notation (+)
. Description complète ici dans le Oracle® Database SQL Language Reference 11g Release 1 (11.1) :
Oracle vous recommande d'utiliser la syntaxe
FROM
clauseOUTER JOIN
Plutôt que l'opérateur de jointure Oracle. Les requêtes de jointure externe qui utilisent l'opérateur de jointure Oracle(+)
Sont soumises aux règles et restrictions suivantes, qui ne s'appliquent pas à la syntaxeFROM
clauseOUTER JOIN
:
- Vous ne pouvez pas spécifier l'opérateur
(+)
Dans un bloc de requête qui contient également la syntaxe de jointure de clauseFROM
.- L'opérateur
(+)
Ne peut apparaître que dans la clauseWHERE
ou, dans le contexte de la corrélation gauche (lors de la spécification de la clauseTABLE
) dans la clauseFROM
et ne peut être appliqué qu'à une colonne d'une table ou d'une vue.- Si A et B sont joints par plusieurs conditions de jointure, vous devez utiliser l'opérateur
(+)
Dans toutes ces conditions. Si vous ne le faites pas, Oracle Database renverra uniquement les lignes résultant d'une simple jointure, mais sans avertissement ni erreur pour vous informer que vous n'avez pas les résultats d'une jointure externe.- L'opérateur
(+)
Ne produit pas de jointure externe si vous spécifiez une table dans la requête externe et l'autre table dans une requête interne.- Vous ne pouvez pas utiliser l'opérateur
(+)
Pour joindre une table à lui-même, bien que les auto-jointures soient valides.Par exemple, l'instruction suivante n'est pas valide:
SELECT employee_id, manager_id FROM employees WHERE employees.manager_id(+) = employees.employee_id;
Cependant, l'auto-jointure suivante est valide:
SELECT e1.employee_id, e1.manager_id, e2.employee_id FROM employees e1, employees e2 WHERE e1.manager_id(+) = e2.employee_id;
- L'opérateur
(+)
Ne peut être appliqué qu'à une colonne, pas à une expression arbitraire. Cependant, une expression arbitraire peut contenir une ou plusieurs colonnes marquées avec l'opérateur(+)
.- Une condition
WHERE
contenant l'opérateur(+)
Ne peut pas être combinée avec une autre condition à l'aide de l'opérateur logiqueOR
.- Une condition
WHERE
ne peut pas utiliser la condition de comparaisonIN
pour comparer une colonne marquée avec l'opérateur(+)
Avec une expression.Si la clause
WHERE
contient une condition qui compare une colonne du tableau B avec une constante, l'opérateur(+)
Doit être appliqué à la colonne pour qu'Oracle renvoie les lignes du tableau A pour lesquelles il a généré des valeurs nulles pour cette colonne. Sinon, Oracle ne renvoie que les résultats d'une simple jointure.Dans une requête qui effectue des jointures externes de plus de deux paires de tables, une seule table peut être la table générée par null pour une seule autre table. Pour cette raison, vous ne pouvez pas appliquer l'opérateur
(+)
Aux colonnes de B dans la condition de jointure pour A et B et la condition de jointure pour B et C. Reportez-vous àSELECT
pour la syntaxe d'un élément externe joindre.
Je suis d'accord avec la réponse de Tony Miller et je voudrais ajouter qu'il y a aussi quelques choses que vous ne pouvez PAS faire avec le synthax (+):
b.id = a.id (+) AND c.id = a.id (+)
n'est pas une clause acceptable)La notation est toujours prise en charge à partir d'Oracle 10 (et je crois 11). Son utilisation est considérée comme "à l'ancienne" et n'est pas aussi portable que la syntaxe ANSI JOIN. Il est également considéré comme beaucoup moins lisible, bien que si vous venez du fond +, vous habituer à ANSI JOIN peut prendre un peu de temps. La chose importante à savoir avant de lancer des brickbats chez Oracle est qu'ils ont développé leur + syntaxe avant que le comité ANSI ait terminé les définitions des jointures.
Il n'y a aucune différence de performances; ils expriment la même chose.
Edit: Par "pas aussi portable" j'aurais dû dire "uniquement pris en charge dans Oracle SQL"
La réponse la plus complète est évidemment celle de nagul .
Un ajout pour ceux qui recherchent une traduction/mappage rapide vers la syntaxe 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(+);
L'une des bonnes raisons d'utiliser la syntaxe [~ # ~] ansi [~ # ~] sur l'ancienne Oracle La syntaxe de jointure est qu'il n'y a aucune chance de créer accidentellement un produit cartésien . Avec un plus grand nombre de tables, il y a une chance de manquer une jointure implicite avec l'ancienne syntaxe de jointure Oracle, cependant, avec la syntaxe ANSI, vous ne pouvez manquer aucune jointure car vous devez explicitement les mentionner.
Différence entre la syntaxe de jointure externe Oracle et la syntaxe ANSI/ISO .
JOINTURE EXTÉRIEURE GAUCHE -
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);
JOINTURE EXTERNE DROITE -
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);
JOINTURE EXTÉRIEURE COMPLÈTE -
Avant le support natif du hash fulljoint1 dans 11gR1, Oracle convertirait en interne le FULL OUTER JOIN de la manière suivante -
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);
Jetez un oeil à this .
J'utilise la notation (+), car presque toutes les requêtes liées à Oracle Apps r12 sont basées sur cela. Je n'ai pas vu une seule requête SQL avec une expression "join" standard dans les requêtes Oracle APPS (même celles fournies par Oracle lui-même). Si vous ne me croyez pas, recherchez simplement les informations liées aux applications Oracle sur Google. Par exemple: requêtes liées aux immobilisations
notation Oracle (+) est uniquement utilisé dans Oracle, qui est spécifique au fournisseur. Et, notation de jointure standard ANSI peut être tilisé dans n'importe quel SGBDR (comme Sql Server, MySql etc.). Sinon, il n'y a aucune différence entre la notation Oracle (+) et la notation Join standard ANSI.
Si vous utilisez la notation de jointure standard ANSI dans votre requête SQL, vous pouvez utiliser la même requête dans n'importe quel SGBDR. Et, si vous êtes portage votre base de données d'Oracle vers tout autre SGBDR dans cette condition, vous devez tiliser la syntaxe ANSI.