Когда я должен использовать, Начинаются / Блоки Конца и ключевое слово Движения в SQL Server?

bobjs может сделать это:

var sFormat = "My name is {0} and I am {1} years old."; 
var result = bob.string.formatString(sFormat, "Bob", 29); 
console.log(result); 
//output: 
//========== 
// My name is Bob and I am 29 years old. 

99
задан a_horse_with_no_name 2 June 2015 в 07:51
поделиться

6 ответов

GO похож на конец сценария.

У вас может быть несколько операторов CREATE TABLE, разделенных GO. Это способ изолировать одну часть скрипта от другой, но отправить все в одном блоке.


BEGIN и END такие же, как {and} в C / ++ / #, Java и т. Д.

Они связывают логический блок кода. Я обычно использую BEGIN и END в начале и в конце хранимой процедуры, но там это не обязательно. Там, где это необходимо, так это для циклов, операторов IF и т. Д., Когда вам нужно более одного шага ...

IF EXISTS (SELECT * FROM my_table WHERE id = @id)
BEGIN
   INSERT INTO Log SELECT @id, 'deleted'
   DELETE my_table WHERE id = @id
END
106
ответ дан 24 November 2019 в 05:04
поделиться

Вам нужно BEGIN ... END, чтобы создать блок, охватывающий более одного оператора. Итак, если вы хотите сделать две вещи в одной «ветке» оператора IF или если вы хотите сделать более одной операции в теле цикла WHILE, вам нужно заключить эти операторы в скобки с BEGIN ... END.

Ключевое слово GO не является частью SQL. Он используется только Query Analyzer для разделения скриптов на «пакеты», которые выполняются независимо.

35
ответ дан 24 November 2019 в 05:04
поделиться

GO не является ключевым словом в SQL Server; это разделитель партий. GO завершает серию заявлений. Это особенно полезно, когда вы используете что-то вроде SQLCMD. Представьте, что вы вводите операторы SQL в командной строке. Вы не обязательно хотите, чтобы это выполнялось каждый раз, когда вы заканчиваете инструкцию, поэтому SQL Server ничего не делает, пока вы не введете «GO».

Аналогичным образом, перед запуском вашего пакета вам часто нужно, чтобы некоторые объекты были видимыми. Например, предположим, что вы создаете базу данных, а затем запрашиваете ее. Вы не можете написать:

CREATE DATABASE foo;
USE foo;
CREATE TABLE bar;

, потому что foo не существует для пакета, который выполняет CREATE TABLE. Вам нужно будет сделать следующее:

CREATE DATABASE foo;
GO
USE foo;
CREATE TABLE bar;
25
ответ дан 24 November 2019 в 05:04
поделиться

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

BEGIN и END необходимы для любых операторов процедурного типа с несколькими строками кода для обработки. Они понадобятся вам для циклов и курсоров WHILE (которых вы, конечно, избегаете, если это вообще возможно) и операторов IF (ну, технически они вам не нужны для состояния IF, которое имеет только одну строку кода, но легче поддерживать код, если вы всегда вставляете их после IF). Операторы CASE также используют END, но не имеют BEGIN.

2
ответ дан 24 November 2019 в 05:04
поделиться

BEGIN и END получили хороший ответ от других.

Как указывает Гэри, GO - это пакетный разделитель, используемый большинством клиентских инструментов Microsoft, таких как isql, sqlcmd, анализатор запросов и студия управления SQL Server. (По крайней мере, некоторые инструменты позволяют изменять разделитель пакетов. Я никогда не видел применения для изменения разделителя пакетов.)

Чтобы ответить на вопрос о том, когда использовать GO, нужно знать, когда должен быть разделены на пакеты.

Некоторые операторы должны быть первым оператором пакета.

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

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

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

В связи с тем, что указал Дэйв Маркел, бывают случаи, когда синтаксический анализ завершается неудачно, потому что 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".
10
ответ дан 24 November 2019 в 05:04
поделиться

После того, как я сегодня решил эту проблему, мое мнение таково: BEGIN ... END код в скобках точно так же, как {....} на языках C, например блоки кода для if ... else и циклов

GO используется (должен использоваться), когда последующие операторы полагаются на объект, определенный предыдущим оператором. База данных USE - хороший пример выше, но следующее также вас укусит:

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-синтаксический анализатор SQL Server, в отличие от Oracle, не может понять, что вы определяете новый символ в первой строке и что можно ссылаться в следующих строках. Он не «видит» символ, пока не встретит токен GO, который сообщает ему выполнить предыдущий SQL с момента последнего GO, после чего символ применяется к базе данных и становится видимым для синтаксического анализатора.

Почему он не обрабатывает точку с запятой просто как семантический разрыв и не применяет инструкции по отдельности, я не знаю и хотел бы, чтобы это было. Единственный бонус, который я вижу, это то, что вы можете поместить оператор print () непосредственно перед GO, и если какой-либо из операторов не сработает, печать не будет выполнена. Хотя много хлопот ради незначительной выгоды.

2
ответ дан 24 November 2019 в 05:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: