Quando devo usare un punto e virgola contro una barra in Oracle SQL?


179

Questa settimana abbiamo discusso della mia azienda su come dovremmo scrivere i nostri script SQL.

Sfondo: il nostro database è Oracle 10g (l'aggiornamento a 11 presto). Il nostro team DBA utilizza SQLPlus per distribuire i nostri script in produzione.

Ora, abbiamo avuto una distribuzione recentemente non riuscita perché aveva usato sia un punto e virgola che una barra ( /). Il punto e virgola era alla fine di ogni istruzione e la barra era tra le istruzioni.

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

In seguito sono stati aggiunti alcuni trigger nello script, alcune viste create e alcune stored procedure. Avere entrambe le istruzioni ;e ha /causato l'esecuzione di ciascuna istruzione due volte causando errori (specialmente sugli inserti, che dovevano essere univoci).

In SQL Developer ciò non accade, in TOAD ciò non accade. Se si eseguono determinati comandi, questi non funzioneranno senza il comando /.

In PL / SQL se si dispone di un sottoprogramma (DECLARE, BEGIN, END) il punto e virgola utilizzato verrà considerato come parte del sottoprogramma, quindi è necessario utilizzare la barra.

Quindi la mia domanda è questa: se il tuo database è Oracle, qual è il modo corretto di scrivere il tuo script SQL? Dato che sai che il tuo DB è Oracle, dovresti sempre usare il /?


1
Nel caso in cui qualcuno stia eseguendo un'esportazione del database con SQLDeveloper, è presente una casella di controllo denominata "Terminator" che, quando selezionata, utilizza i punti e virgola per terminare ogni istruzione. Questa opzione è selezionata per impostazione predefinita. Deseleziona per rimuovere i punti e virgola e per evitare la duplicazione
dell'istruzione

7
Solo per inutilmente trascinare a morte questo vecchio thread, menzionerò che il linguaggio SQL non ha punti e virgola. È semplicemente il carattere di terminazione predefinito in SQL * Plus (è possibile impostarlo sqlterminatorsu !se lo si desidera) e questa convenzione tende a essere seguita da altri strumenti. Il linguaggio PL / SQL utilizza tuttavia i punti e virgola come elemento di sintassi obbligatorio.
William Robertson,

Risposte:


31

È una questione di preferenza, ma preferisco vedere gli script che usano costantemente la barra - in questo modo tutte le "unità" di lavoro (creazione di un oggetto PL / SQL, esecuzione di un blocco anonimo PL / SQL ed esecuzione di un'istruzione DML) possono essere scelto più facilmente a occhio.

Inoltre, se alla fine si passa a qualcosa come Ant per la distribuzione, si semplifica la definizione di target per avere un delimitatore di istruzioni coerente.


1
questa risposta non spiega perché /o ;vedi la risposta di @a_horse_with_no_name o @Mr_Moneybags per più contesto
Kay

333

So che questo è un vecchio thread, ma mi sono appena imbattuto in esso e sento che questo non è stato spiegato completamente.

C'è una grande differenza in SQL * Plus tra il significato di a /e a ;perché funzionano in modo diverso.

Il ;termina un'istruzione SQL, mentre /esegue qualsiasi cosa si trovi nel "buffer" corrente. Quindi quando usi a ; e a /l'istruzione viene effettivamente eseguita due volte.

Si può facilmente vedere che usando un /dopo aver eseguito un'istruzione:

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

In questo caso si nota effettivamente l'errore.


Ma supponendo che esista uno script SQL come questo:

drop table foo;
/

E questo viene eseguito da SQL * Plus, quindi sarà molto confuso:

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

È /richiesto principalmente per eseguire istruzioni incorporate ;come CREATE PROCEDUREun'istruzione.


2
@amis, sono nuovo di Oracle e ho lo stesso problema. Questa domanda è molto utile, ma tutte le risposte hanno dato una spiegazione sul "perché" non sul "miglior modo" di lavorare o in qualche modo per risolvere il problema. Quindi, se ho capito bene, non c'è modo di avere solo uno script e tenerlo utilizzabile per tutti gli strumenti ... o lo scopri in qualche modo?
ceinmart,

5
@ceinmart: il "modo migliore" è definire uno (e solo uno) strumento per eseguire script SQL - e la "correttezza" di uno script viene convalidata usando quello strumento. Simile ad avere un compilatore per il tuo linguaggio di programmazione o una versione specifica del tuo ambiente di runtime (Java 7, .Net 4.0, PHP 5.x, ...)
a_horse_with_no_name

1
Buona risposta. Sono solo io o Oracle è sciocco e arcaico rispetto ad altri DB? Ho usato molto Sybase e sembra molto più intuitivo.
splashout

1
@splashout: bene, se vuoi eseguire istruzioni che contengono il delimitatore predefinito ( ;), allora devi trovare un modo per specificare un delimitatore alternativo
a_horse_with_no_name

97

Volevo chiarire un altro uso tra il ;e il/

In SQLPLUS:

  1. ; significa "termina l'istruzione corrente, eseguila e memorizzala nel buffer SQLPLUS"
  2. <newline>dopo un'istruzione DML (SELECT, UPDATE, INSERT, ...) o alcuni tipi di istruzioni DDL (Creazione di tabelle e viste) (che non contengono ;), significa che memorizza l'istruzione nel buffer ma non la esegue.
  3. /dopo aver inserito un'istruzione nel buffer (con uno spazio vuoto <newline>) significa "eseguire il DML o DDL o PL / SQL nel buffer.
  4. RUNoppure Rè un comando sqlsplus per mostrare / generare l'SQL nel buffer ed eseguirlo. Non terminerà un'istruzione SQL.
  5. / durante l'immissione di un DML o DDL o PL / SQL significa "terminare l'istruzione corrente, eseguirla e archiviarla nel buffer SQLPLUS"

NOTA: poiché ;vengono utilizzati per far terminare PL / SQL un'istruzione ;non può essere utilizzata da SQLPLUS per indicare "termina l'istruzione corrente, eseguirla e archiviarla nel buffer SQLPLUS" perché vogliamo che l'intero blocco PL / SQL sia completamente nel buffer, quindi eseguirlo. I blocchi PL / SQL devono terminare con:

END;
/

22

Quasi tutte le distribuzioni Oracle vengono eseguite tramite SQL * Plus (quello strano piccolo strumento da riga di comando utilizzato dal DBA). E in SQL * Plus una barra solitaria in pratica significa "rieseguire l'ultimo comando SQL o PL / SQL che ho appena eseguito".

Vedere

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

La regola pratica sarebbe quella di utilizzare la barra con le cose che fanno BEGIN .. ENDo dove è possibile utilizzare CREATE OR REPLACE.

Per inserti che devono essere unici

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>)

14

Da quanto ho capito, tutte le istruzioni SQL non necessitano di barra poiché verranno eseguite automaticamente alla fine del punto e virgola, incluse le istruzioni DDL, DML, DCL e TCL.

Per altri blocchi PL / SQL, tra cui procedure, funzioni, pacchetti e trigger, poiché si tratta di programmi a più righe, Oracle ha bisogno di un modo per sapere quando eseguire il blocco, quindi dobbiamo scrivere una barra in avanti alla fine di ogni blocco per lascia che Oracle lo esegua.


1

Uso la barra in avanti solo una volta alla fine di ogni script, per dire a sqlplus che non ci sono più righe di codice. Nel mezzo di una sceneggiatura, non uso una barra.


Quindi ordini alla fine le cose che richiedono / (come sottoprogrammi e trigger)? Cosa succede se si hanno più trigger? Ho eseguito un test e solo il primo viene eseguito a meno che non abbia un / tra ognuno. Mi sto perdendo qualcosa?
amischiefr,

Cerco di evitarlo (se possibile), ma se non ci riesco (come nei trigger), utilizzo i punti e virgola e le barre esattamente come negli script ufficiali che generano gli schemi di esempio di Oracle: download.oracle.com/docs /cd/B19306_01/server.102/b14198/… Per il problema degli inserti, provo a separare gli script che creano oggetti da quelli che popolano le tabelle.
Jonathan,

1
Siamo spiacenti, ma questo non risponde alla domanda.
DerMike,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.