it-swarm.com.de

GO Nach jeder T-SQL-Anweisung

Was ist der Grund für die Verwendung der GO-Anweisung nach jeder SQL-Anweisung? Ich verstehe, dass GO das Ende des Stapels signalisiert und/oder die Reputation von Anweisungen ermöglicht, aber welchen Vorteil hat es, wenn es nach jeder Anweisung verwendet wird.

Ich bin nur neugierig, da viele Microsoft-Dokumentationen usw. nach jeder Aussage damit begonnen haben oder ich es gerade erst bemerkt habe.

Was gilt als Best Practice?

34
TheIdiot

Bevor Sie antworten, wann und warum Sie es verwenden sollen, müssen Sie zunächst genau verstehen, was GO ist und was nicht.

Das Schlüsselwort GO wird von SQL Server Management Studio und SQLCMD verwendet, um eine Sache und nur eine Sache zu kennzeichnen: Das Ende eines Stapels von Anweisungen. In der Tat können Sie sogar ändern was Sie verwenden, um Stapel zu etwas anderem als "GO" zu beenden:

enter image description here

Der obige Screenshot ist eine konfigurierbare Option in SSMS.

Aber was ist eine Charge? Diese BOL-Referenz sagt es am besten:

Ein Stapel ist eine Gruppe von einer oder mehreren Transact-SQL-Anweisungen , die gleichzeitig von einer Anwendung zur Ausführung an SQL Server gesendet werden.

So einfach ist das. Es ist nur eine benutzerdefinierte Methode, mit der eine Anwendung (ja ... eine Anwendung) Anweisungen an SQL Server sendet. Sehen wir uns ein Anwendungsbeispiel dafür an. Ich werde PowerShell verwenden, um nachzuahmen, was eine Anwendung tun würde, um Anweisungen und Stapel an SQL Server zu senden:

$ConnectionString = "data source = SomeSQLInstance; initial catalog = AdventureWorks2012; trusted_connection = true; application name = BatchTesting;"

try {
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection($ConnectionString)
    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
    $SqlCmd.Connection = $SqlConnection

    # first batch of statements
    #
    $SqlCmd.CommandText = "
        select * from humanresources.department where departmentid = 1;
        select * from humanresources.department where departmentid = 2;
        select * from humanresources.department where departmentid = 3;
        select * from humanresources.department where departmentid = 4;"

    # execute the first batch
    #
    $SqlConnection.Open()
    $SqlCmd.ExecuteNonQuery()
    $SqlConnection.Close()

    # second batch of statements
    #
    $SqlCmd.CommandText = "
        select * from humanresources.department where departmentid = 5;
        select * from humanresources.department where departmentid = 6;
        select * from humanresources.department where departmentid = 7;
        select * from humanresources.department where departmentid = 8;"

    # execute the second batch
    #
    $SqlConnection.Open()
    $SqlCmd.ExecuteNonQuery()
    $SqlConnection.Close()
}
catch {
    $SqlCmd.Dispose()
    $SqlConnection.Dispose()
    Write-Error $_.Exception
}

Die Kommentare verraten es, aber Sie können oben sehen, dass wir programmgesteuert zwei Stapel an SQL Server senden. Lassen Sie uns das jedoch überprüfen. Ich wähle hier Extended Events:

create event session BatchTesting
on server
add event sqlserver.sql_batch_starting
(
    set
        collect_batch_text = 1
    where
    (
        sqlserver.client_app_name = N'BatchTesting'
    )
),
add event sqlserver.sql_batch_completed
(
    set
        collect_batch_text = 1
    where
    (
        sqlserver.client_app_name = N'BatchTesting'
    )
),
add event sqlserver.sql_statement_starting
(
    set
        collect_statement = 1
    where
    (
        sqlserver.client_app_name = N'BatchTesting'
    )
),
add event sqlserver.sql_statement_completed
(
    set
        collect_statement = 1
    where
    (
        sqlserver.client_app_name = N'BatchTesting'
    )
)
add target package0.event_file
(
    set
        filename = N'<MyXelLocation>\BatchTesting.xel'
);
go

alter event session BatchTesting
on server
state = start;
go

In dieser XEvents-Sitzung werden lediglich die Anweisungen und Stapel erfasst, die von einer Anwendung mit dem Namen "BatchTesting" Starten und abgeschlossen werden. (Wenn Sie meine Verbindungszeichenfolge in meinem PowerShell-Codebeispiel bemerken, können Sie schnell einen bestimmten Urheber von anzeigen Ereignisse unter Verwendung des Verbindungszeichenfolgenparameters "Anwendungsname" und Herausfiltern davon).

Nachdem ich den PowerShell-Code ausgeführt habe, um diese Stapel und Anweisungen zu senden, werden die folgenden Ergebnisse angezeigt:

enter image description here

Wie Sie dem Screenshot entnehmen können, ist klar, wie die Anweisungen in zwei verschiedene Stapel unterteilt sind. Dies zeigt sich auch an den Mitteln, mit denen wir die Stapel aufgerufen haben. Und wenn wir uns das batch_text Des ersten Auftretens von sql_batch_starting Anschauen, können wir alle in diesem Stapel enthaltenen Anweisungen sehen:

    select * from humanresources.department where departmentid = 1;
    select * from humanresources.department where departmentid = 2;
    select * from humanresources.department where departmentid = 3;
    select * from humanresources.department where departmentid = 4;

Mit dieser Erklärung von was ist eine Charge, jetzt kommt die Antwort auf Ihre Frage von wann, um Stapel zu beenden. Die Regeln für Chargen finden Sie unter diese BOL-Referenz zu Chargen :

Die Anweisungen CREATE DEFAULT, CREATE FUNCTION, CREATE PROCEDURE, CREATE RULE, CREATE SCHEMA, CREATE TRIGGER und CREATE VIEW können nicht mit anderen Anweisungen in einem Stapel kombiniert werden. Die Anweisung CREATE muss den Stapel starten. Alle anderen Anweisungen, die in diesem Stapel folgen, werden als Teil der Definition der ersten CREATE-Anweisung interpretiert.

Eine Tabelle kann nicht geändert werden, und dann werden die neuen Spalten im selben Stapel referenziert.

Wenn eine EXECUTE-Anweisung die erste Anweisung in einem Stapel ist, ist das Schlüsselwort EXECUTE nicht erforderlich. Das Schlüsselwort EXECUTE ist erforderlich, wenn die Anweisung EXECUTE nicht die erste Anweisung im Stapel ist.

Ebenso können bestimmte Laufzeitfehler (Kompilierungsfehler ermöglichen nicht, dass die Ausführung eines Stapels gestartet wird), die während eines Stapels auftreten, unterschiedliche Verhaltensweisen verursachen: den Stapel vollständig abzubrechen oder den Stapel fortzusetzen und nur die fehlerhafte Anweisung abzubrechen (siehe oben) link gibt zwei wirklich gute Beispiele: Ein arithmetischer Überlauffehler stoppt beispielsweise die Ausführung des Stapels, während ein Fehler bei der Verletzung von Einschränkungen nur verhindert, dass die aktuelle Anweisung abgeschlossen wird, der Stapel jedoch weiterhin ausgeführt wird.

Wie viele Dinge in unserem Beruf wird jedoch die persönliche Präferenz eine große treibende Kraft dafür sein, wie Sie als Einzelperson und Verfasser von T-SQL-Code Stapel beenden . Einige Leute definieren Stapel nur explizit, wenn sie unbedingt (siehe oben für diese Anforderungen) und andere beenden Stapel programmgesteuert zu 100%, auch wenn sie nur eine einzelne Anweisung in einem Abfragefenster in SSMS ausführen. Die meisten Menschen fallen normalerweise irgendwo in die Mitte dieser beiden Grenzen. Für das, was es wert ist, haben Anweisungsabschlusszeichen die gleiche Anhängerschaft mit auch sehr wenigen erzwungenen Anforderungen. Ein großer Teil davon ist der Codestil , bei dem er nicht erzwungen wird (in SSMS und SQLCMD).

51
Thomas Stringer