Прежде чем ответить, когда его использовать и почему, сначала необходимо понять, что именно GO
, а что нет.
Ключевое слово GO
используется SQL Server Management Studio и SQLCMD для обозначения одного и только одного: конца пакета утверждений. Фактически, вы можете даже изменить то, что вы используете для завершения пакетов, на что-то другое, кроме «GO»:
Этот скриншот выше - опция в SSMS, которая настраивается.
Но что такое партия? Эта ссылка BOL говорит это лучше всего:
Пакет представляет собой группу из одного или нескольких операторов Transact-SQL, одновременно отправляемых из приложения на SQL Server для выполнения.
Просто как тот. Это просто пользовательский способ, которым приложение (да ... приложение) отправляет операторы в SQL Server. Давайте посмотрим на пример приложения этого вида. Я буду использовать PowerShell для имитации того, что приложение будет делать для отправки операторов и пакетов на 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
}
Комментарии выдают это, но вы можете видеть выше, что мы программно отправляем две партии SQL Server. Давайте проверим это, хотя. Мой выбор здесь - использовать расширенные события:
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
Все, что делает этот сеанс XEvents, - это захват операторов и пакетов, которые запускаются и завершаются из приложения с именем "BatchTesting"
(если вы заметили мою строку подключения в моем примере кода PowerShell, это быстрый способ взглянуть на конкретного источника событий с помощью приложения "" имя "параметр строки подключения и отфильтровывание этого).
После выполнения кода PowerShell для отправки этих пакетов и операторов я вижу следующие результаты:
Как вы можете видеть на скриншоте, ясно, как операторы делятся на две разные партии, что также очевидно по средствам, которые мы использовали для вызова пакетов. И если мы посмотрим на batch_text
первое вхождение sql_batch_starting
, мы можем увидеть все операторы, включенные в этот пакет:
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;
С этим объяснением того, что такое партия, теперь приходит ответ на ваш вопрос о том, когда прекратить партии. Правила для партий находятся на этой ссылке BOL относительно партий :
Операторы CREATE DEFAULT, CREATE FUNCTION, CREATE PROCEDURE, CREATE RULE, CREATE SCHEMA, CREATE TRIGGER и CREATE VIEW нельзя объединять с другими операторами в пакете. Оператор CREATE должен запустить пакет. Все остальные операторы, которые следуют в этом пакете, будут интерпретированы как часть определения первого оператора CREATE.
Таблица не может быть изменена, а затем новые столбцы, на которые есть ссылки в том же пакете.
Если оператор EXECUTE является первым оператором в пакете, ключевое слово EXECUTE не требуется. Ключевое слово EXECUTE необходимо, если оператор EXECUTE не является первым оператором в пакете.
Аналогичным образом, определенные ошибки времени выполнения (ошибки компиляции не позволяют запустить выполнение пакета), возникающие во время пакета, могут вызывать различное поведение: полностью прервать пакет или продолжить пакет и прервать только оператор-нарушитель (см. Выше). link дает два действительно хороших примера: например, ошибка арифметического переполнения остановит выполнение пакета, в то время как ошибка нарушения ограничения будет только препятствовать выполнению текущего оператора, но пакет продолжит выполнение).
Как и многие вещи в нашей профессии, личные предпочтения будут огромной движущей силой того, как вы, как человек и автор кода T-SQL, завершаете пакеты. Некоторые люди явно определяют пакеты только тогда, когда они абсолютно необходимы (см. Выше для этих требований), а другие завершают пакеты программно 100% времени , даже когда они выполняют только один оператор в окне запросов в SSMS. Большинство людей обычно попадают где-то посередине этих двух границ. Что бы ни стоило, терминаторы операторов имеют то же самое следование с очень небольшим количеством обязательных требований. Большая часть всего этого - стиль кода , где он не применяется (в SSMS и SQLCMD).