214 votes

Quand dois-je utiliser un point-virgule ou une barre oblique dans Oracle SQL ?

Nous avons eu un débat cette semaine dans mon entreprise sur la façon dont nous devrions écrire nos scripts SQL.

Contexte : Notre base de données est Oracle 10g (mise à niveau vers 11 prochainement). Notre équipe de DBA utilise SQLPlus afin de déployer nos scripts en production.

Nous avons récemment eu un déploiement qui a échoué parce qu'il avait utilisé à la fois un point-virgule et une barre oblique ( / ). Le point-virgule se trouvait à la fin de chaque déclaration et la barre oblique entre les déclarations.

alter table foo.bar drop constraint bar1;
/
alter table foo.can drop constraint can1;
/

Quelques triggers ont été ajoutés plus tard dans le script, quelques vues ont été créées ainsi que quelques procédures stockées. Ayant à la fois le ; et le / entraînait l'exécution de chaque instruction deux fois, ce qui provoquait des erreurs (en particulier pour les insertions, qui devaient être uniques).

Dans SQL Developer cela ne se produit pas, dans TOAD cela ne se produit pas. Si vous exécutez certaines commandes, elles ne fonctionneront pas sans l'attribut / en eux.

En PL/SQL, si vous avez un sous-programme (DECLARE, BEGIN, END), le point-virgule utilisé sera considéré comme faisant partie du sous-programme, vous devez donc utiliser la barre oblique.

Ma question est donc la suivante : Si votre base de données est Oracle, quelle est la bonne façon d'écrire votre script SQL ? Puisque vous savez que votre base de données est Oracle, devez-vous toujours utiliser l'option / ?

1 votes

Si quelqu'un fait une exportation de base de données avec SQLDeveloper, il y a une case à cocher appelée "Terminator" qui, lorsqu'elle est sélectionnée, utilise des points-virgules pour terminer chaque déclaration. Cette option est sélectionnée par défaut. Désélectionnez-la pour supprimer les points-virgules et éviter l'exécution d'instructions en double.

10 votes

Afin d'alimenter inutilement ce vieux sujet, je mentionnerai que le langage SQL n'a pas de point-virgule. Il s'agit simplement du caractère de fin de ligne par défaut dans SQL*Plus (vous pouvez paramétrer sqlterminator à ! si vous voulez) et cette convention tend à être suivie par d'autres outils. Le langage PL/SQL utilise toutefois le point-virgule comme élément syntaxique obligatoire.

1 votes

@WilliamRobertson Vous devriez ajouter votre commentaire en tant que réponse puisque cette information est manquante dans les réponses.

375voto

a_horse_with_no_name Points 100769

Je sais que c'est un vieux fil de discussion, mais je viens de tomber dessus et j'ai l'impression que cela n'a pas été expliqué complètement.

Il y a une énorme différence dans SQL*Plus entre la signification d'une / et un ; parce qu'ils fonctionnent différemment.

Le site ; termine une instruction SQL, tandis que le / exécute ce qui se trouve dans le "tampon" actuel. Ainsi, lorsque vous utilisez un ; et a / l'instruction est en fait exécutée deux fois.

Vous pouvez facilement constater que l'utilisation d'un / après avoir exécuté une déclaration :

SQL*Plus: Release 11.2.0.1.0 Production on Wed Apr 18 12:37:20 2012

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning and OLAP options

SQL> drop table foo;

Table dropped.

SQL> /
drop table foo
           *
ERROR at line 1:
ORA-00942: table or view does not exist

Dans ce cas, on remarque effectivement l'erreur.

Mais en supposant qu'il y ait un script SQL comme celui-ci :

drop table foo;
/

Si cela est exécuté à partir de SQL*Plus, ce sera très confus :

SQL*Plus: Release 11.2.0.1.0 Production on Wed Apr 18 12:38:05 2012

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning and OLAP options

SQL> @drop

Table dropped.

drop table foo
           *
ERROR at line 1:
ORA-00942: table or view does not exist

Le site / est principalement nécessaire pour exécuter les déclarations qui ont intégré ; comme CREATE PROCEDURE , CREATE FUNCTION , CREATE PACKAGE et pour toute BEGIN...END blocs.

2 votes

@amis, je suis nouveau sur Oracle et je rencontre le même problème. Cette question est très utile, mais toutes les réponses ont donné une explication sur le "pourquoi" et non la "meilleure façon" de travailler ou un moyen de contourner cela. Donc, si j'ai bien compris, il n'y a aucun moyen d'avoir un seul script et de le garder utilisable pour tous les outils... ou découvrez-vous un moyen ?

6 votes

@ceinmart : la "meilleure façon" est de définir un (et un seul) outil pour exécuter les scripts SQL - et la "correction" d'un script est validée en utilisant cet outil. C'est un peu comme avoir un seul compilateur pour votre langage de programmation ou une version spécifique de votre environnement d'exécution (Java 7, .Net 4.0, PHP 5.x, ...).

2 votes

Bonne réponse. Est-ce que c'est moi ou est-ce qu'Oracle est bizarre et archaïque par rapport aux autres bases de données ? J'ai utilisé beaucoup de Sybase et cela semble beaucoup plus intuitif.

111voto

Mr_Moneybags Points 102

Je voulais clarifier un peu plus l'utilisation entre le ; et le /

Dans SQLPLUS :

  1. ; signifie "terminer l'instruction courante, l'exécuter et la stocker dans le tampon SQLPLUS".
  2. <newline> après une instruction D.M.L. (SELECT, UPDATE, INSERT,...) ou certains types d'instructions D.D.L. (Création de tables et de vues) (qui ne contiennent pas d'instructions de type ; ), cela signifie qu'il faut stocker l'instruction dans le tampon mais ne pas l'exécuter.
  3. / après avoir saisi une déclaration dans la mémoire tampon (avec un blanc <newline> ) signifie "exécuter le D.M.L. ou D.D.L. ou PL/SQL dans le tampon.
  4. RUN ou R est une commande sqlsplus pour afficher/exploiter le SQL dans le tampon et l'exécuter. Elle ne terminera pas une déclaration SQL.
  5. / pendant l'entrée d'une D.M.L. ou D.D.L. ou PL/SQL signifie "terminer l'instruction en cours, l'exécuter et la stocker dans le tampon SQLPLUS".

NOTE : Parce que ; sont utilisées par PL/SQL pour terminer une déclaration ; ne peut pas être utilisé par SQLPLUS pour signifier "terminer l'instruction courante, l'exécuter et la stocker dans le tampon de SQLPLUS" car nous voulons que le bloc PL/SQL entier soit complètement dans le tampon, puis l'exécuter. Les blocs PL/SQL doivent se terminer par :

END;
/

0 votes

Vous avez dit que ; ne peut pas être utilisé signifie le point (1) quand il s'agit de PL/SQL, mais pourquoi n'est-ce pas le cas ? END; suffisant pour marquer la cessation d'activité ? N'est-ce pas sans ambiguïté ?

32voto

dpbradley Points 7496

C'est une question de préférence, mais je préfère voir des scripts qui utilisent systématiquement le slash - de cette façon, toutes les "unités" de travail (création d'un objet PL/SQL, exécution d'un bloc anonyme PL/SQL et exécution d'une instruction DML) peuvent être repérées plus facilement à l'œil.

De plus, si vous passez finalement à quelque chose comme Ant pour le déploiement, cela simplifiera la définition des cibles pour avoir un délimiteur de déclaration cohérent.

9 votes

Cette réponse n'explique pas pourquoi / ou ; voir la réponse de @a_horse_with_no_name ou @Mr_Moneybags pour plus de contexte

23voto

jva Points 1663

Presque tous les déploiements d'Oracle se font par le biais de SQL*Plus (ce petit outil de ligne de commande bizarre que votre DBA utilise). Et dans SQL*Plus, une barre oblique isolée signifie essentiellement "réexécuter la dernière commande SQL ou PL/SQL que je viens d'exécuter".

Voir

http://ss64.com/ora/syntax-sqlplus.html

La règle de base est d'utiliser la barre oblique avec les choses qui font BEGIN .. END ou où vous pouvez utiliser CREATE OR REPLACE .

Pour les insertions qui doivent être uniques, utilisez

INSERT INTO my_table ()
SELECT <values to be inserted>
FROM dual
WHERE NOT EXISTS (SELECT 
                  FROM my_table
                  WHERE <identify data that you are trying to insert>)

16voto

Jerry Points 58

D'après ce que j'ai compris, toutes les instructions SQL n'ont pas besoin de barre oblique car elles s'exécutent automatiquement à la fin des points-virgules, y compris les instructions DDL, DML, DCL et TCL.

Pour les autres blocs PL/SQL, y compris les procédures, les fonctions, les paquets et les déclencheurs, étant donné qu'il s'agit de programmes à lignes multiples, Oracle a besoin d'un moyen de savoir quand exécuter le bloc, nous devons donc écrire une barre oblique à la fin de chaque bloc pour permettre à Oracle de l'exécuter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X