Когда в SQL Server следует использовать GO, а когда - точку с запятой;?

100

Меня всегда смущало, когда следует использовать ключевое слово GO после команд и нужна ли точка с запятой в конце команд. В чем различия и почему / когда я должен их использовать?

Когда я запускаю Generate-script в SQL Server Management Studio, кажется, что он везде использует GO, но не точку с запятой.

Аид
источник
3
возможный дубликат В чем разница между ";" а «GO» в TSQL (SQL 2008)?
JohnFx

Ответы:

93

GOотносится только к SSMS - это не настоящий Transact SQL, он просто сообщает SSMS, что нужно последовательно отправлять операторы SQL между каждым из них GOв отдельных пакетах.

Это ;разделитель операторов SQL, но по большей части механизм может интерпретировать, где ваши операторы разбиты.

Основное исключение и место, где ;чаще всего используется, - это оператор выражения общей таблицы.

cjk
источник
5
Акцент на том, GOчто часть T-SQL не ;является, а есть
msarchet
2
MERGEЗаявление должно быть прекращено с запятой.
однажды, когда
15
Обновление: в SQL Server 2012 НЕ рекомендуется использовать точки с запятой, то есть они потребуются в следующей версии. Таким образом, рекомендуется использовать точку с запятой, так как в случае миграции (и поскольку это стандарт) потребуется меньше работы. Источник: technet.microsoft.com/en-us/library/ms143729.aspx или книга по SQL Server 2012: shop.oreilly.com/product/0790145321978.do
Павел Бульван
1
SQL 2014 по-прежнему указывает точку с запятой, как требуется для следующей версии. Интересно, когда это станет устаревшим. technet.microsoft.com/en-us/library/ms143729.aspx
Фрэнк
2
+ Buli не заявляет, что ;это устарело, НЕ использовать его, это не рекомендуется, то есть, согласно источнику, он станет обязательным.
cjk
78

Причина, по которой вы видите так много GO в сгенерированных сценариях DDL, заключается в следующем правиле о пакетах.

Операторы CREATE DEFAULT, CREATE FUNCTION, CREATE PROCEDURE, CREATE RULE, CREATE TRIGGER и CREATE VIEW нельзя комбинировать с другими операторами в пакете. Оператор CREATE должен начинать пакет. Все остальные операторы, следующие за этим пакетом, будут интерпретироваться как часть определения первого оператора CREATE.

Один из вариантов использования сгенерированного DDL - создание нескольких объектов в одном файле. По этой причине генератор DDL должен иметь возможность генерировать пакеты. Как говорили другие, инструкция GO завершает пакет.

Конрад Фрикс
источник
10
Это единственный, кто действительно ответил на вопрос "... когда использовать GO ...?" часть вопроса.
Roimer
Мне кажется, что GO завершает операторы, которые создают объекты, содержащие SQL, которые могут содержать; терминатор заявления. В другой СУБД я видел возможность установить строку завершения. Например, вы можете указать, что операторы заканчиваются двумя вертикальными чертами ||. Затем вы можете выполнить CREATE PROCEDURE ... много SQL, заканчивающееся на; ... || а двойная труба завершает оператор CREATE PROCEDURE. Итак, мой вопрос: аналогично ли это заявлению MS GO? Во-вторых, можете ли вы переопределить строку завершения в SQLSERVER?
youcantryreachingme
@youcantryreachingme Не знаю, было ли это правдой в 2010 году, но, похоже, можно. См. SSMS: Batch Separator . Я не уверен, каковы пределы этого,
Конрад Фрикс,
34

ИДТИ

Go - это пакетный разделитель. Это означает, что все в этом пакете является локальным для этого конкретного пакета.

Любые объявления переменных, табличных переменных и т. Д. Не проходят через GOоператоры.

Таблицы #Temp являются локальными для соединения, поэтому они охватывают операторы GO.

Точка с запятой

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

В большинстве случаев самого синтаксиса оператора достаточно, чтобы определить конец оператора.

Однако CTE требуют, чтобы первым был оператор WITH, поэтому вам нужна точка с запятой перед WITH.

Радж Мор
источник
4
MERGEЗаявление должно быть прекращено с запятой.
однажды, когда
11

Для завершения каждого оператора SQL следует использовать точку с запятой. Это определено в стандартах SQL,

Конечно, чаще всего SQL Server позволяет вам опустить терминатор оператора, но зачем приобретать дурные привычки?

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

;WITH ...

что, на мой взгляд, выглядит очень странно. Я полагаю, что это имеет смысл в онлайн-форуме, когда вы не можете сказать качество кода, в который он будет вставлен.

Кроме того, MERGEоператор должен заканчиваться точкой с запятой. Вы видите здесь закономерность? Это несколько новых дополнений к TSQL, которые полностью соответствуют стандартам SQL. Похоже, что команда SQL Server намерена ввести обязательное использование терминатора с запятой.

один день, когда
источник
2
« что, на мой взгляд, выглядит очень странно » - не могу не согласиться. И постоянное повторение этого приводит к странным вопросам вроде этого или этого
a_horse_with_no_name
SQL Server не позволяет вам быть небрежным - он позволяет вам опустить лишний терминатор оператора; T-SQL, как и большинство других SQL, не является чистым стандартным SQL, который больше похож на абстрактный базовый класс - не используется на практике в пользу собственного диалекта механизма БД.
ProfK 03
@ProfK: спасибо за то, что вы добавили знаки препинания в свой комментарий, что облегчило мне чтение и понимание, особенно символы-терминаторы предложения. Хотя ваше использование дефисов не соответствует стандартному английскому ...
однажды, когда
8

GO - это терминатор пакета, точка с запятой - терминатор оператора.

вы будете использовать GO, если хотите иметь несколько операторов create proc в одном скрипте, потому что create proc должен быть первым оператором в пакете. Если вы используете общие табличные выражения, тогда оператор перед его завершением должен быть точкой с запятой.

SQLMenace
источник
MERGEЗаявление должно быть прекращено с запятой.
однажды, когда