Przed odpowiedzią, kiedy i dlaczego go użyć, najważniejsze GO
jest, aby dokładnie zrozumieć, co jest, a co nie.
GO
Słowo kluczowe jest używane przez SQL Server Management Studio i SQLCMD w celu oznaczenia jednej rzeczy i tylko jednej rzeczy: końca zestawu instrukcji. W rzeczywistości możesz nawet zmienić to, czego używasz do kończenia partii na coś innego niż „GO”:
Powyższy zrzut ekranu jest konfigurowalną opcją w ramach SSMS.
Ale co to jest partia? To odniesienie do BOL mówi najlepiej:
Partia to grupa co najmniej jednej instrukcji Transact-SQL wysłanej w tym samym czasie z aplikacji do programu SQL Server w celu wykonania.
Proste. Jest to po prostu niestandardowy sposób, w jaki aplikacja (tak ... aplikacja) wysyła instrukcje do programu SQL Server. Zobaczmy przykład tego wyglądający na aplikację. Użyję programu PowerShell, aby naśladować działanie aplikacji w celu wysyłania instrukcji i partii do programu SQL Server:
$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
}
Komentarze zdradzają, ale widać powyżej, że programowo wysyłamy dwie partie do SQL Server. Sprawdźmy to jednak. Moim wyborem jest skorzystanie z Rozszerzonych zdarzeń:
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
Sesja XEvent polega wyłącznie na przechwytywaniu instrukcji i partii, które rozpoczynają się i kończą z aplikacji o nazwie "BatchTesting"
(jeśli zauważysz mój ciąg połączenia w moim przykładzie kodu PowerShell, jest to szybki sposób na sprawdzenie konkretnego inicjatora zdarzeń za pomocą „aplikacji” nazwa ”parametr ciągu połączenia i odfiltrowanie tego).
Po uruchomieniu kodu programu PowerShell w celu wysłania tych partii i instrukcji widzę następujące wyniki:
Jak widać na zrzucie ekranu, jasne jest, w jaki sposób zestawienia dzielą się na dwie różne partie, co jest również widoczne za pomocą środków, które nazywaliśmy partiami. A jeśli spojrzymy batch_text
na pierwsze wystąpienie sql_batch_starting
, możemy zobaczyć wszystkie instrukcje zawarte w tej partii:
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;
Z tym wyjaśnieniem, co to jest partia, teraz pojawia się odpowiedź na pytanie, kiedy należy kończyć partie. Reguły dotyczące partii znajdują się w tym dokumencie referencyjnym BOL dotyczącym partii :
UTWÓRZ DOMYŚLNE, UTWÓRZ FUNKCJĘ, UTWÓRZ PROCEDURĘ, UTWÓRZ ZASADĘ, UTWÓRZ SCHEMAT, UTWÓRZ TRIGGER i UTWÓRZ instrukcje nie mogą być łączone z innymi instrukcjami w partii. Instrukcja CREATE musi rozpocząć partię. Wszystkie pozostałe instrukcje, które następują w tej partii, będą interpretowane jako część definicji pierwszej instrukcji CREATE.
Tabeli nie można zmienić, a następnie do nowych kolumn, do których odwołuje się ta sama partia.
Jeśli instrukcja EXECUTE jest pierwszą instrukcją w partii, słowo kluczowe EXECUTE nie jest wymagane. Słowo kluczowe EXECUTE jest wymagane, jeśli instrukcja EXECUTE nie jest pierwszą instrukcją w partii.
Podobnie, niektóre błędy w czasie wykonywania (błędy kompilacji nie pozwalają na uruchomienie wykonywania wsadu), które występują podczas wsadu, mogą powodować różne zachowania: całkowite przerwanie wsadu lub kontynuowanie wsadu i tylko przerwanie instrukcji naruszającej prawo (powyższe link podaje dwa naprawdę dobre przykłady: na przykład błąd przepełnienia arytmetycznego zatrzyma wykonanie partii, podczas gdy błąd naruszenia ograniczenia uniemożliwi tylko wykonanie bieżącej instrukcji, ale partia będzie kontynuowana).
Podobnie jak wiele innych rzeczy w naszym zawodzie, osobiste preferencje będą ogromną siłą napędową stojącą za tym, jak Ty jako osoba i autor kodu T-SQL kończysz partie. Niektóre osoby jawnie definiują partie tylko wtedy, gdy są absolutnie konieczne (te wymagania powyżej), a inne kończą partie programowo w 100% przypadków , nawet jeśli wykonują tylko jedną instrukcję w oknie zapytania w SSMS. Większość ludzi zwykle spada gdzieś pośrodku tych dwóch granic. Pod względem wartości terminatory instrukcji mają to samo, a także bardzo niewiele wymuszonych wymagań. Dużą część tego wszystkiego stanowi styl kodu , w którym nie jest on wymuszany (w SSMS i SQLCMD).