Wann muss ich in Oracle SQL ein Semikolon gegen einen Schrägstrich verwenden?

177

Wir haben diese Woche in meinem Unternehmen einige Debatten darüber geführt, wie wir unsere SQL-Skripte schreiben sollen.

Hintergrund: Unsere Datenbank ist Oracle 10g (baldiges Upgrade auf 11). Unser DBA-Team verwendet SQLPlus, um unsere Skripte für die Produktion bereitzustellen.

Jetzt hatten wir kürzlich eine Bereitstellung, die fehlgeschlagen ist, weil sowohl ein Semikolon als auch ein Schrägstrich ( /) verwendet wurden. Das Semikolon stand am Ende jeder Anweisung und der Schrägstrich stand zwischen den Anweisungen.

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

Später im Skript wurden einige Trigger hinzugefügt, einige Ansichten erstellt und einige gespeicherte Prozeduren. Sowohl die ;als auch die /Anweisung haben dazu geführt, dass jede Anweisung zweimal ausgeführt wurde, was zu Fehlern führte (insbesondere bei den Einfügungen, die eindeutig sein mussten).

In SQL Developer passiert dies nicht, in TOAD nicht. Wenn Sie bestimmte Befehle ausführen, funktionieren diese ohne die /darin enthaltenen nicht.

Wenn Sie in PL / SQL ein Unterprogramm (DECLARE, BEGIN, END) haben, wird das verwendete Semikolon als Teil des Unterprogramms betrachtet, sodass Sie den Schrägstrich verwenden müssen.

Meine Frage lautet also: Wenn Ihre Datenbank Oracle ist, wie können Sie Ihr SQL-Skript richtig schreiben? Da Sie wissen, dass Ihre Datenbank Oracle ist, sollten Sie immer die verwenden /?

amischiefr
quelle
1
Wenn jemand einen Datenbankexport mit SQLDeveloper ausführt, gibt es ein Kontrollkästchen namens "Terminator", das bei Auswahl Semikolons verwendet, um jede Anweisung zu beenden. Diese Option ist standardmäßig ausgewählt.
Deaktivieren Sie diese Option
7
Um diesen alten Thread sinnlos zu Tode zu prügeln, möchte ich erwähnen, dass die SQL-Sprache kein Semikolon enthält. Es ist lediglich das Standardterminatorzeichen in SQL * Plus (Sie können festlegen sqlterminator, !wenn Sie möchten), und diese Konvention wird in der Regel von anderen Tools befolgt. Die PL / SQL-Sprache verwendet jedoch Semikolons als obligatorisches Syntaxelement.
William Robertson

Antworten:

31

Es ist eine Frage der Präferenz, aber ich bevorzuge Skripte, die konsistent den Schrägstrich verwenden - auf diese Weise können alle "Arbeitseinheiten" (Erstellen eines PL / SQL-Objekts, Ausführen eines anonymen PL / SQL-Blocks und Ausführen einer DML-Anweisung) ausgeführt werden leichter mit dem Auge herausgesucht.

Wenn Sie schließlich zur Bereitstellung zu Ant wechseln, wird die Definition von Zielen vereinfacht, um ein konsistentes Anweisungsbegrenzer zu erhalten.

dpbradley
quelle
Diese Antwort erklärt nicht warum /oder ;siehe die Antwort von @a_horse_with_no_name oder @Mr_Moneybags für mehr Kontext
Kay
331

Ich weiß, dass dies ein alter Thread ist, aber ich bin nur darauf gestoßen und ich habe das Gefühl, dass dies nicht vollständig erklärt wurde.

In SQL * Plus gibt es einen großen Unterschied zwischen der Bedeutung von a /und a, ;da sie unterschiedlich funktionieren.

Das ;beendet eine SQL-Anweisung, während das /alles ausführt, was sich im aktuellen "Puffer" befindet. Wenn Sie also a ; und a verwenden, wird /die Anweisung tatsächlich zweimal ausgeführt.

Sie können dies leicht erkennen, indem Sie a verwenden, /nachdem Sie eine Anweisung ausgeführt haben:

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 diesem Fall bemerkt man den Fehler tatsächlich.


Angenommen, es gibt ein SQL-Skript wie dieses:

drop table foo;
/

Und dies wird in SQL * Plus ausgeführt, dann ist dies sehr verwirrend:

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

Das /ist hauptsächlich erforderlich, um Anweisungen auszuführen, die ;wie eine CREATE PROCEDUREAnweisung eingebettet sind .

ein Pferd ohne Name
quelle
1
@amis, ich bin neu bei Oracle und habe das gleiche Problem. Diese Frage ist sehr nützlich, aber alle Antworten gaben eine Erklärung über das "Warum", nicht die "beste Art zu arbeiten" oder eine Möglichkeit, dies zu umgehen. Wenn ich es richtig verstanden habe, gibt es keine Möglichkeit, nur ein Skript zu haben und es für alle Tools verwendbar zu halten ... oder entdecken Sie einen Weg?
Ceinmart
5
@ceinmart: Der "beste Weg" besteht darin, ein (und nur ein) Tool zum Ausführen von SQL-Skripten zu definieren - und die "Richtigkeit" eines Skripts wird mit diesem Tool überprüft. Ähnlich wie bei einem Compiler für Ihre Programmiersprache oder einer bestimmten Version Ihrer Laufzeitumgebung (Java 7, .NET 4.0, PHP 5.x, ...)
a_horse_with_no_name
1
Gute Antwort. Ist es nur ich oder ist Oracle im Vergleich zu anderen DBs doof und archaisch? Ich habe viel Sybase verwendet und es scheint viel intuitiver zu sein.
Splashout
1
@splashout: Nun, wenn Sie Anweisungen ausführen möchten, die das Standardtrennzeichen ( ;) enthalten, müssen Sie einen Weg finden, ein alternatives Trennzeichen anzugeben
a_horse_with_no_name
97

Ich wollte etwas mehr Verwendung zwischen dem ;und dem klären/

In SQLPLUS:

  1. ; bedeutet "Beenden Sie die aktuelle Anweisung, führen Sie sie aus und speichern Sie sie im SQLPLUS-Puffer"
  2. <newline>Nach einer DML-Anweisung (SELECT, UPDATE, INSERT, ...) oder einigen Arten von DDL-Anweisungen (Erstellen von Tabellen und Ansichten) (die no enthalten ;) bedeutet dies, dass die Anweisung im Puffer gespeichert, aber nicht ausgeführt wird.
  3. /Nach Eingabe einer Anweisung in den Puffer (mit einem Leerzeichen <newline>) bedeutet "DML oder DDL oder PL / SQL im Puffer ausführen".
  4. RUNoder Rist ein Befehl sqlsplus, um die SQL im Puffer anzuzeigen / auszugeben und auszuführen. Eine SQL-Anweisung wird nicht beendet.
  5. / Während der Eingabe einer DML oder DDL oder PL / SQL bedeutet "Beenden Sie die aktuelle Anweisung, führen Sie sie aus und speichern Sie sie im SQLPLUS-Puffer".

ANMERKUNG: Da ;für PL / SQL zum ;Beenden einer Anweisung keine Anweisung von SQLPLUS verwendet werden kann, bedeutet dies "Beenden der aktuellen Anweisung, Ausführen und Speichern im SQLPLUS-Puffer", da der gesamte PL / SQL-Block vollständig im Puffer, dann führen Sie es aus. PL / SQL-Blöcke müssen enden mit:

END;
/
Mr_Moneybags
quelle
22

Fast alle Oracle-Bereitstellungen erfolgen über SQL * Plus (das seltsame kleine Befehlszeilentool, das Ihr DBA verwendet). Und in SQL * Plus bedeutet ein einzelner Schrägstrich im Grunde "den letzten SQL- oder PL / SQL-Befehl, den ich gerade ausgeführt habe, erneut ausführen".

Sehen

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

Als Faustregel gilt, Schrägstriche für Dinge zu verwenden, die funktionieren BEGIN .. ENDoder wo Sie sie verwenden können CREATE OR REPLACE.

Für Einsätze, die eindeutig verwendet werden müssen

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
quelle
14

Nach meinem Verständnis benötigen alle SQL-Anweisungen keinen Schrägstrich, da sie am Ende von Semikolons automatisch ausgeführt werden, einschließlich DDL-, DML-, DCL- und TCL-Anweisungen.

Für andere PL / SQL-Blöcke, einschließlich Prozeduren, Funktionen, Pakete und Trigger, muss Oracle wissen, wann der Block ausgeführt werden muss, da es sich um mehrzeilige Programme handelt. Daher müssen wir am Ende jedes Blocks einen Schrägstrich schreiben Lassen Sie Oracle es ausführen.

Jerry
quelle
1

Ich verwende den Schrägstrich am Ende jedes Skripts nur einmal, um sqlplus mitzuteilen, dass keine Codezeilen mehr vorhanden sind. In der Mitte eines Skripts verwende ich keinen Schrägstrich.

Jonathan
quelle
Bestellen Sie also am Ende Dinge, für die das / erforderlich ist (z. B. Unterprogramme und Trigger)? Was ist, wenn Sie mehrere Auslöser haben? Ich habe einen Test durchgeführt und nur der erste wird ausgeführt, es sei denn, zwischen jedem steht ein /. Vermisse ich etwas
Amischiefr
Ich versuche es zu vermeiden (wenn möglich), aber wenn ich es nicht kann (wie bei Triggern), verwende ich die Semikolons und Schrägstriche genau so, wie sie in den offiziellen Skripten verwendet werden, die die Beispielschemata von oracle generieren: download.oracle.com/docs /cd/B19306_01/server.102/b14198/… Für das Einfügungsproblem versuche ich, die Skripte, die Objekte erstellen, von denen zu trennen, die die Tabellen füllen .
Jonathan
1
Entschuldigung, aber dies beantwortet die Frage nicht.
DerMike