Quand dois-je utiliser un point-virgule par rapport à une barre oblique dans Oracle SQL?

179

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 bientôt). Notre équipe DBA utilise SQLPlus pour déployer nos scripts en production.

Maintenant, nous avons eu un déploiement récemment qui a échoué car il avait utilisé à la fois un point-virgule et une barre oblique ( /). Le point-virgule se trouvait à la fin de chaque instruction et la barre oblique entre les instructions.

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

Certains déclencheurs ont été ajoutés plus tard dans le script, certaines vues ont été créées ainsi que certaines procédures stockées. Le fait d'avoir à la fois le ;et le /fait que chaque instruction s'exécute deux fois, ce qui provoque des erreurs (en particulier sur les insertions, qui doivent ê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 /elles.

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 le /?

amischiefr
la source
1
Dans le cas où quelqu'un effectue 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 instruction. Cette option est sélectionnée par défaut.
Désélectionner
7
Juste pour fouetter inutilement ce vieux fil à mort, je mentionnerai que le langage SQL n'a pas de point-virgule. Il est simplement le caractère de terminaison par défaut dans SQL * Plus (vous pouvez définir sqlterminatorà !si vous le souhaitez) et cette convention a tendance à suivre par d' autres outils. Le langage PL / SQL utilise cependant des points-virgules comme élément de syntaxe obligatoire.
William Robertson

Réponses:

31

C'est une question de préférence, mais je préfère voir des scripts qui utilisent systématiquement la barre oblique - 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é plus facilement à l'œil nu.

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 d'instructions cohérent.

dpbradley
la source
1
cette réponse n'explique pas pourquoi /ou ne ;voyez pas la réponse de @a_horse_with_no_name ou @Mr_Moneybags pour plus de contexte
Kay
333

Je sais que c'est un vieux fil, mais je suis juste tombé dessus et je pense que cela n'a pas été complètement expliqué.

Il existe une énorme différence dans SQL * Plus entre la signification de a /et a ;car ils fonctionnent différemment.

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

Vous pouvez facilement voir cela en utilisant un /après l'exécution d'une instruction:

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 réellement l'erreur.


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

drop table foo;
/

Et ceci est exécuté à partir de SQL * Plus, alors ce sera très déroutant:

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 /est principalement nécessaire pour exécuter des instructions intégrées ;comme une CREATE PROCEDUREinstruction.

un cheval sans nom
la source
2
@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 sur la «meilleure façon» de travailler ou sur un moyen de contourner ce problème. 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?
ceinmart
5
@ceinmart: la "meilleure façon" est de définir un (et un seul) outil pour exécuter des scripts SQL - et la "correction" d'un script est validée à l'aide de cet outil. Similaire à avoir un 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, ...)
a_horse_with_no_name
1
Bonne réponse. Est-ce juste moi ou Oracle est-il maladroit et archaïque par rapport aux autres bases de données? J'ai beaucoup utilisé Sybase et cela me semble beaucoup plus intuitif.
splashout
1
@splashout: eh bien, si vous voulez exécuter des instructions contenant le délimiteur par défaut ( ;), vous devez trouver un moyen de spécifier un autre délimiteur
a_horse_with_no_name
97

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 la mémoire tampon SQLPLUS"
  2. <newline>après une instruction DML (SELECT, UPDATE, INSERT, ...) ou certains types d'instructions DDL (création de tables et vues) (qui ne contiennent aucun ;), cela signifie, stocker l'instruction dans le tampon mais ne pas l'exécuter.
  3. /après avoir entré une instruction dans le tampon (avec un blanc <newline>) signifie «exécuter le DML ou DDL ou PL / SQL dans le tampon.
  4. RUNou Rest une commande sqlsplus pour afficher / sortir le SQL dans le tampon et l'exécuter. Cela ne mettra pas fin à une instruction SQL.
  5. / lors de la saisie d'un DML ou DDL ou PL / SQL signifie "terminer l'instruction en cours, l'exécuter et la stocker dans le tampon SQLPLUS"

REMARQUE: car ils ;sont utilisés pour PL / SQL pour terminer une instruction ;ne peuvent pas être utilisés par SQLPLUS pour signifier «terminer l'instruction en cours, l'exécuter et la stocker dans la mémoire tampon SQLPLUS» car nous voulons que tout le bloc PL / SQL soit complètement dans le tampon, puis exécutez-le. Les blocs PL / SQL doivent se terminer par:

END;
/
Mr_Moneybags
la source
22

Presque tous les déploiements Oracle sont effectués via SQL * Plus (ce petit outil de ligne de commande étrange que votre DBA utilise). Et dans SQL * Plus, une seule barre oblique 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 d'or serait d'utiliser une barre oblique avec des choses qui font BEGIN .. ENDou où vous pouvez utiliser CREATE OR REPLACE.

Pour les inserts qui doivent être à usage unique

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>)
jva
la source
14

D'après ce que je comprends, toutes les instructions SQL n'ont pas besoin de barre oblique car elles s'exécuteront 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 packages et les déclencheurs, car ce sont des programmes à plusieurs lignes, 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 laissez Oracle l'exécuter.

Jerry
la source
1

Je n'utilise la barre oblique qu'une seule fois à la fin de chaque script, pour dire à sqlplus qu'il n'y a plus de lignes de code. Au milieu d'un script, je n'utilise pas de barre oblique.

Jonathan
la source
Alors, commandez-vous les choses qui nécessitent le / (comme les sous-programmes et les déclencheurs) à la fin? Et si vous avez plusieurs déclencheurs? J'ai effectué un test et seul le premier s'exécute à moins qu'il n'ait un / entre chacun. Est-ce que je manque quelque chose?
amischiefr
J'essaie de l'éviter (si possible), mais si je ne peux pas (comme dans les déclencheurs), j'utilise les points-virgules et les barres obliques exactement comme utilisés dans les scripts officiels qui génèrent les exemples de schémas d'oracle: download.oracle.com/docs /cd/B19306_01/server.102/b14198/... Pour le problème des insertions, j'essaye de séparer les scripts qui créent des objets de ceux qui peuplent les tables.
Jonathan
1
Désolé, mais cela ne répond pas à la question.
DerMike