2009-07-24 5 views

Antwort

84

GO ist wie das Ende eines Skripts.

Sie könnten mehrere CREATE TABLE-Anweisungen haben, die durch GO getrennt sind. Es ist eine Möglichkeit, einen Teil des Skripts von einem anderen zu isolieren, aber alles in einem Block zu übertragen.


BEGIN und END sind genauso wie {} und in C/++/#, Java usw.

Sie einen logischen Codeblock gebunden. Ich benutze BEGIN und END am Anfang und am Ende einer gespeicherten Prozedur, aber das ist dort nicht unbedingt notwendig. Wo es notwendig ist, ist für Schleifen und IF-Anweisungen, etc., wo Sie mehr als einen Schritt benötigen ...

IF EXISTS (SELECT * FROM my_table WHERE id = @id) 
BEGIN 
    INSERT INTO Log SELECT @id, 'deleted' 
    DELETE my_table WHERE id = @id 
END 
+0

Haben Sie versucht, einen SP ohne BEGIN und END zu erstellen? IIRC, nur die erste Zeile ist in der SP enthalten, der Rest wird nur dort ausgeführt und dann ... – cjk

+1

Das ist sicherlich nicht meine Erfahrung aus SQL Server 2000 ab. – MatBailie

29

Sie benötigen BEGIN ... END, um einen Block zu erstellen, der mehr als eine Anweisung umfasst. Also, wenn Sie 2 Dinge in einem "Bein" einer IF-Anweisung machen wollten, oder wenn Sie mehr als eine Sache im Körper einer WHILE-Schleife machen wollten, müssten Sie diese Anweisungen mit BEGIN ... ENDE.

Das Schlüsselwort GO ist nicht Teil von SQL. Es wird nur von Query Analyzer verwendet, um Skripts in "Batches" zu unterteilen, die unabhängig voneinander ausgeführt werden.

+1

+1 für schnelleres Tippen :) – MatBailie

+0

+1 Prägnant und genau – Frozenskys

19

GO ist kein Schlüsselwort in SQL Server; Es ist ein Batch-Separator. GO beendet eine Reihe von Anweisungen. Dies ist besonders nützlich, wenn Sie etwas wie SQLCMD verwenden. Stellen Sie sich vor, Sie geben in der Befehlszeile SQL-Anweisungen ein. Sie möchten nicht unbedingt, dass das Objekt jedes Mal ausgeführt wird, wenn Sie eine Anweisung beenden. SQL Server führt also nichts aus, bis Sie "GO" eingeben.

Ebenso müssen Sie vor dem Start Ihres Stapels häufig einige Objekte sichtbar machen. Angenommen, Sie erstellen eine Datenbank und fragen sie ab. Sie können nicht schreiben:

CREATE DATABASE foo; 
USE foo; 
CREATE TABLE bar; 

, weil foo nicht für den Stapel vorhanden ist, der die CREATE TABLE ausführt. Sie müssten dies tun:

CREATE DATABASE foo; 
GO 
USE foo; 
CREATE TABLE bar; 
2

GO endet eine Charge, würden Sie nur sehr selten in Code verwenden müssen. Beachten Sie, dass wenn Sie es in einem gespeicherten Proc verwenden, kein Code nach dem GO ausgeführt wird, wenn Sie den Proc ausführen.

BEGIN und END werden für alle Prozedurtyp-Anweisungen benötigt, die mehrere Zeilen Code verarbeiten müssen. Sie werden sie für WHILE-Schleifen und -Cursors (die Sie, wenn überhaupt möglich, vermeiden werden) und IF-Anweisungen benötigen (technisch gesehen brauchen Sie sie nicht für eine IF-Anweisung, die nur eine Codezeile hat, aber es ist einfacher Pflegen Sie den Code, wenn Sie ihn immer nach einer IF einfügen). CASE-Anweisungen verwenden ebenfalls ein END, haben jedoch keinen BEGIN.

+0

Würde irgendein Code nach dem GO tatsächlich gegen den gespeicherten proc gespeichert? würde die CREATE- oder ALTER-Anweisung nicht so verarbeitet werden, als ob der Code nach dem GO nicht existierte? Und DANN wird der Code nach dem GO ausgeführt, als wäre es ein eigenes Skript? – MatBailie

+0

Was haben Cursor damit zu tun? –

+0

Nun, realistisch, benötigen Sie eine Schleife, um einen Cursor zu verwenden ... – MatBailie

8

BEGIN und END wurden von anderen gut beantwortet.

Wie Gary darauf hinweist, ist GO ein Stapeltrennzeichen, das von den meisten von Microsoft bereitgestellten Clienttools wie isql, sqlcmd, query analyzer und SQL Server Management studio verwendet wird. (Zumindest einige der Werkzeuge erlauben es, den Batch-Separator zu ändern. Ich habe noch nie eine Verwendung zum Ändern des Batch-Separators gesehen.)

Um die Frage zu beantworten, wann GO zu verwenden ist, muss man wissen, wann die SQL in Batches aufgeteilt werden muss.

Einige Anweisungen müssen die erste Anweisung eines Stapels sein.

select 1 
create procedure #Zero as 
    return 0 

auf SQL Server 2000 ist der Fehler:

Msg 111, Level 15, State 1, Line 3 
'CREATE PROCEDURE' must be the first statement in a query batch. 
Msg 178, Level 15, State 1, Line 4 
A RETURN statement with a return value cannot be used in this context. 

auf SQL Server 2005 ist der Fehler weniger hilfreich:

Msg 178, Level 15, State 1, Procedure #Zero, Line 5 
A RETURN statement with a return value cannot be used in this context. 

So verwenden GO Aussagen zu trennen, die sein müssen der Start eines Stapels aus den Anweisungen, die in einem Skript vorangestellt sind.

Wenn ein Skript ausgeführt wird, führen viele Fehler dazu, dass die Ausführung des Stapels gestoppt wird, aber dann sendet der Client einfach den nächsten Stapel, die Ausführung des Skripts wird nicht gestoppt. Ich benutze das oft beim Testen. Ich werde das Skript starten mit der Transaktion beginnen und mit Rollback zu beenden, alle Tests in der Mitte zu tun:

begin transaction 
go 
... test code here ... 
go 
rollback transaction 

Auf diese Weise habe ich immer in den Ausgangszustand zurückkehren, selbst wenn ein Fehler in dem Testcode passiert ist, die beginnen und Rollback-Transaktionsanweisungen, die Teil eines separaten Stapels sind, finden immer noch statt. Wenn sie nicht in separaten Stapeln vorhanden wären, würde ein Syntaxfehler die Transaktion nicht beginnen, da ein Stapel als eine Einheit analysiert wird. Und ein Laufzeitfehler würde den Rollback verhindern.

Wenn Sie ein Installationsskript ausführen und mehrere Stapel in einer Datei haben, führt ein Fehler in einem Stapel nicht dazu, dass das Skript weiterhin ausgeführt wird, was zu Problemen führen kann. (Immer vor der Installation sichern.) Im Zusammenhang mit dem, worauf Dave Markel hingewiesen hat, gibt es Fälle, in denen das Parsing fehlschlägt, weil SQL Server im Datenwörterbuch nach Objekten sucht, die früher im Stapel erstellt wurden, aber das Parsing kann vorher geschehen Alle Anweisungen werden ausgeführt. Manchmal ist das ein Problem, manchmal nicht. Ich kann mir kein gutes Beispiel vorstellen. Aber wenn Sie jemals einen 'X existiert nicht' Fehler bekommen, wenn es durch diese Aussage einfach existiert, brechen Sie in Chargen.

Und eine letzte Notiz. Die Transaktion kann Stapel umfassen. (Siehe oben.) Variablen umfassen keine Stapel.

declare @i int 
set @i = 0 
go 
print @i 

Msg 137, Level 15, State 2, Line 1 
Must declare the scalar variable "@i". 
+1

Das ist, was ich brauchte, danke: "Transaktion kann überspannen Chargen. Variablen nicht überspannen Chargen." – Gary

1

mit diesem Problem Nachdem Ringen heute ist meine Meinung dazu: BEGIN ... Code END Klammern wie {....} tut in C Sprachen, z.B. Codeblöcke für if ... else und loops

GO ist (muss) verwendet werden, wenn sich nachfolgende Anweisungen auf ein Objekt verlassen, das durch eine vorherige Anweisung definiert wurde. USE-Datenbank ist ein gutes Beispiel oben, aber die folgenden finden Sie auch beißen:

alter table foo add bar varchar(8); 
-- if you don't put GO here then the following line will error as it doesn't know what bar is. 
update foo set bar = 'bacon'; 
-- need a GO here to tell the interpreter to execute this statement, otherwise the Parser will lump it together with all successive statements. 

Es scheint mir, das Problem ist folgende: die SQL Server SQL Parser, im Gegensatz zu dem Oracle ein, nicht in der Lage ist, dass Sie zu realisieren‘ Er definiert ein neues Symbol in der ersten Zeile und es ist in Ordnung, in den folgenden Zeilen zu referenzieren. Es "sieht" das Symbol nicht, bis es auf ein GO-Token trifft, das ihm sagt, dass es das vorhergehende SQL seit dem letzten GO ausführen soll. An diesem Punkt wird das Symbol auf die Datenbank angewendet und für den Parser sichtbar.

Warum es nicht nur das Semikolon als semantischen Bruch behandelt und Aussagen einzeln anwendet, weiß ich nicht und wünsche es.Der einzige Bonus, den ich sehen kann, ist, dass Sie eine Anweisung print() direkt vor dem GO setzen können und wenn eine der Anweisungen fehlschlägt, wird der Druck nicht ausgeführt. Viel Ärger für einen kleinen Gewinn.

Verwandte Themen