6 ответов:
Go-это как конец скрипта.
у вас может быть несколько операторов CREATE TABLE, разделенных GO. Это способ изолировать одну часть скрипта от другой, но представить все это в одном блоке.
начало и конец точно такие же, как { и } в C/++/#, Java и т. д.
они связали логический блок кода. Я обычно использую BEGIN и END в начале и конце хранимой процедуры, но это не обязательно там. Где это Это необходимо для циклов, а если операторы и т. д., где вам нужно больше одного шага...
IF EXISTS (SELECT * FROM my_table WHERE id = @id) BEGIN INSERT INTO Log SELECT @id, 'deleted' DELETE my_table WHERE id = @id END
вам нужно начать ... Конец для создания блока, охватывающего более одного оператора. Итак, если вы хотите сделать 2 вещи в одной "ноге" оператора IF или если вы хотите сделать более одной вещи в теле цикла WHILE, вам нужно будет заключить эти утверждения в скобки с помощью BEGIN...КОНЕЦ.
ключевое слово GO не является частью SQL. Он используется только анализатором запросов для разделения сценариев на" пакеты", которые выполняются независимо.
GO-это не ключевое слово в SQL Server; это разделитель пакетов. GO завершает пакет инструкций. Это особенно полезно, когда вы используете что-то вроде SQLCMD. Представьте, что вы вводите инструкции SQL в командной строке. Вы не обязательно хотите, чтобы эта вещь выполнялась каждый раз, когда вы заканчиваете инструкцию, поэтому SQL Server ничего не делает, пока вы не введете "GO".
кроме того, перед запуском пакета вам часто нужно видеть некоторые объекты. Например, предположим, что вы создание базы данных, а затем запрос к ней. Вы не можете написать:
CREATE DATABASE foo; USE foo; CREATE TABLE bar;потому что foo не существует для пакета, который создает таблицу. Вам нужно будет сделать это:
CREATE DATABASE foo; GO USE foo; CREATE TABLE bar;
начало и конец были хорошо ответили другие.
как указывает Гэри, GO-это разделитель пакетов, используемый большинством клиентских инструментов, поставляемых Microsoft, таких как isql, sqlcmd, query analyzer и SQL Server Management studio. (По крайней мере, некоторые инструменты позволяют изменять разделитель партий. Я никогда не видел использования для изменения разделителя пакетов.)
чтобы ответить на вопрос, когда использовать GO, нужно знать, когда SQL должен быть разделен на партии.
некоторые операторы должны быть первым оператором пакета.
select 1 create procedure #Zero as return 0на SQL Server 2000 ошибка:
Msg 111, Level 15, State 1, Line 3 'CREATE PROCEDURE' must be the first statement in a query batch. Msg 178, Level 15, State 1, Line 4 A RETURN statement with a return value cannot be used in this context.на SQL Server 2005 ошибка менее полезна:
Msg 178, Level 15, State 1, Procedure #Zero, Line 5 A RETURN statement with a return value cannot be used in this context.используйте
GOчтобы отделить операторы, которые должны быть началом пакета от операторов, которые предшествуют ему в скрипте.при запуске скрипта многие ошибки приведут к остановке выполнения пакета, но тогда клиент просто отправьте следующий пакет, выполнение скрипта не остановится. Я часто использую это в тестировании. Я начну скрипт с начала транзакции и закончу с отката, делая все тестирование в середине:
begin transaction go ... test code here ... go rollback transactionтаким образом, я всегда возвращаюсь в начальное состояние, даже если в тестовом коде произошла ошибка, инструкции begin и rollback transaction, являющиеся частью отдельных пакетов, все еще происходят. Если бы они не были в отдельных пакетах, то синтаксическая ошибка сохраняла бы транзакцию begin от происходящего, так как пакет анализируется как единица. И ошибка выполнения будет держать откат от происходящего.
кроме того, если вы выполняете сценарий установки и имеете несколько пакетов в одном файле, ошибка в одном пакете не удержит скрипт от продолжения работы, что может оставить беспорядок. (Всегда резервное копирование перед установкой.)
в связи с тем, что указал Дэйв Маркел, есть случаи, когда синтаксический анализ завершится неудачей, потому что SQL Server ищет в словаре данных объекты, созданные ранее в пакете, но синтаксический анализ может произойти до выполнения каких-либо инструкций. Иногда это проблема, иногда нет. Я не могу придумать хороший пример. Но если вы когда-нибудь получите ошибку "X не существует", когда она явно будет существовать, этот оператор разбивается на пакеты.
и последнее замечание. Транзакция может охватывать пакеты. (Смотреть выше.) Переменные не охватывают пакеты.
declare @i int set @i = 0 go print @i Msg 137, Level 15, State 2, Line 1 Must declare the scalar variable "@i".
GO завершает пакет, вам будет очень редко нужно использовать его в коде. Имейте в виду, что если вы используете его в сохраненном proc, никакой код после GO не будет выполнен при выполнении proc.
начало и конец необходимы для любых операторов процедурного типа с несколькими строками кода для обработки. Вам понадобятся они для циклов WHILE и курсоров (которые вы будете избегать, если это вообще возможно, конечно), и если заявления (ну технически вам не нужны они для утверждения IF, которое имеет только один строка кода, но легче поддерживать код, если вы всегда ставите их после IF). Операторы CASE также используют конец, но не имеют начала.
после борьбы с этой проблемой сегодня мое мнение такое: НАЧИНАТЬ...Конец скобки код так же, как {....} делает на языках C, например, блоки кода для if...еще и петли
GO используется (должен использоваться), когда последующие операторы полагаются на объект, определенный предыдущим оператором. Использование базы данных является хорошим примером выше, но следующее также укусит вас:
alter table foo add bar varchar(8); -- if you don't put GO here then the following line will error as it doesn't know what bar is. update foo set bar = 'bacon'; -- need a GO here to tell the interpreter to execute this statement, otherwise the Parser will lump it together with all successive statements.Мне кажется, проблема заключается в следующем: SQL Server SQL Parser, в отличие от Oracle, не может понимаю, что вы определяете новый символ в первой строке и что это нормально ссылаться в следующих строках. Он не "видит" символ, пока не встретит токен GO, который говорит ему выполнить предыдущий SQL с момента последнего GO, после чего символ применяется к базе данных и становится видимым для синтаксического анализатора.
почему он просто не рассматривает точку с запятой как семантический разрыв и не применяет операторы индивидуально, я не знаю и хочу, чтобы это было. Единственный бонус, который я вижу, это то, что вы можете поместить оператор print () непосредственно перед переходом, и если какой-либо из операторов не будет выполнен, печать не будет выполняться. Много проблем для незначительного выигрыша, хотя.
Comments