2013-12-20 1 views
54

Я знаю это в SQL Server GOis considered a batch separator.SQL Server: что такое пакетные операторы (т. Е. Использование «GO»)?

Мой вопрос: Какой смысл иметь сепаратор партии? Какую пользу это дает вам и почему вы хотите ее использовать?

Пример: Я часто видел, что он используется в коде SQL следующим образом, и я не понимаю, почему это считается лучшей практикой. Насколько я могу сказать код будет такой же, без всех GO утверждений:

USE AdventureWorks2012; 
GO 
BEGIN TRANSACTION; 
GO 
IF @@TRANCOUNT = 0 
BEGIN 
    SELECT FirstName, MiddleName 
    FROM Person.Person WHERE LastName = 'Adams'; 
    ROLLBACK TRANSACTION; 
    PRINT N'Rolling back the transaction two times would cause an error.'; 
END; 
ROLLBACK TRANSACTION; 
PRINT N'Rolled back the transaction.'; 
GO 

(источник: technet documentation):

+3

Возможный дубликат [Что такое использование GO в SQL Server Management Studio?] (Http://stackoverflow.com/questions/2299249/what-is-the-use-of-go-in-sql -server-management-studio) –

+4

@JohnnyBones, нет, это не то же самое (я даже связался с этим сообщением в моем вопросе). Этот пост в основном говорит, что GO - это разделитель партий, но мой вопрос задает вопрос, что классный разделитель подходит для –

+0

. Посмотрите на ответ, предоставленный tvanfosson в этом вопросе (26 upvotes). –

ответ

28

В примере там никакой пользы вообще.

Однако множество заявлений должны быть единственными в партии.

таких как CREATE PROCEDURE.

Также часто после внесения изменений схемы (например, добавления нового столбца в существующую таблицу) операторы, использующие новую схему, должны быть скомпилированы отдельно в другой партии.

Вообще альтернатива подачи отдельных партий, разделенных GO, чтобы выполнить SQL в дочернем пакете с использованием EXEC

+1

Это имеет смысл, спасибо. Я также видел, что он использовался в сценариях обновления схемы базы данных после каждой операции alter/create table, даже если последовательные операции не зависели от предыдущего. Есть ли какие-либо основания для этого, или это было бы практикой, когда разработчикам не приходилось думать о своих SQL-ответах. –

+1

@ Zain. Ну, это не наносит большого вреда (кроме увеличения числа поездок в сети) и, вероятно, экономит некоторые ошибки, когда операции действительно зависят от предыдущих. –

+0

Похоже, что код SQL нужно разделить на две партии, когда вторая партия работает с объектами, созданными первой партией. Другими словами, если вторая партия требует, чтобы механизм планирования SQL использовал артефакты, которые еще не существуют, что испортит планирование. Это верно? –

4

Как Martain сказал, заявление, таким как CREATE PROCEDURE должна быть единственными в партии.

Например, я использую пакетные разделители всякий раз, когда создаю хранимые процедуры и добавляю разрешения для определенного пользователя. Если я упустил «go», я бы закончил с хранимой процедурой, которая предоставляет права каждый раз, когда она запускается. Таким образом, я могу написать их в одно и то же время и убедиться, что я не пишу хранимые процедуры, которые ломаются, когда я их вызываю. Например

create procedure [procedurename] 
(parameters) 
as begin 

select prefname, lastname from people 

end 

go 

grant execute on [procedurename] to [username] 
22

Как TechNet says, GO это означает конец SQL партии к SQL утилит. Например, когда SQL Server Management Studio сталкивается с разделителем пакетов, он знает, что весь текст до сих пор является независимым SQL-запросом.

Мы используем аналогичную технику в нашем программном обеспечении. Мы сохраняем все наши процессы, сценарии схем, преобразования данных и т. Д. В файлах сценариев SQL (проверяется на исходный контроль). Когда наш установщик читает один из этих файлов сценариев, GO сообщает нашему парсеру «вы можете запустить SQL, который вы уже прочитали».

Приятная особенность такого разделителя пакетов, как GO, заключается в том, что вы можете включить два SQL-запроса вместе в том же скрипте, который обычно вызывает ошибку.Например, попробуйте удалить и заново создать ту же хранимую процедуру в том же файле сценария:

if exists (select * from sys.procedures where name = 'sp_test') 
    drop procedure sp_test 

create procedure sp_test as 
begin 
    select 1 
end 

Если запустить приведенный выше код, вы получите сообщение об ошибке:

Msg 156, Level 15, State 1, Procedure sp_test, Line 5 Incorrect syntax near the keyword 'begin'.

И SSMS будет показать вам ошибку:

Incorrect syntax. 'CREATE PROCEDURE' must be the only statement in a batch.

Использование пакетного сепаратора может помочь вам получить эту ошибку:

if exists (select * from sys.procedures where name = 'sp_test') 
    drop procedure sp_test 
GO 
create procedure sp_test as 
begin 
    select 1 
end 

Это очень удобно, если, скажем, вам нужен один SQL-скрипт в исходном элементе управления для хранения хранимой процедуры или функции. Мы часто используем эту схему.

Еще одна интересная вещь, которую вы можете сделать, это использовать его, чтобы запустить запрос несколько раз:

INSERT INTO MyTable (...) ... 
GO 10 -- run all the above 10 times! 

Как the answers to this SO question показывают, вы можете также настроить его на то, что вы хотите. Если вы хотите возиться со своими коллегами, установите разделитель партии в нечто вроде «WHERE» вместо «GO». Весело! :)

+7

Такая забава может быть опасна для здоровья. –

Смежные вопросы