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

Проверяя некоторый код в Интернете и скрипты, созданные SQL Server Management Studio, я заметил, что некоторые операторы заканчиваются точкой с запятой.

Итак, когда я должен использовать его?

Ответ 1

От SQLServerCentral.Com article от Ken Powers:

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

Символ с запятой - это терминатор утверждения. Он является частью стандарта ANSI SQL-92, но никогда не использовался в Transact-SQL. Действительно, можно было кодировать T-SQL в течение многих лет, не встречая точку с запятой.

Использование

Есть две ситуации, в которых вы должны использовать точку с запятой. В первой ситуации вы используете выражение Common Table Expression (CTE), а CTE не является первым оператором в пакете. Во-вторых, вы выдаете оператор Service Broker, а оператор Service Broker не является первым оператором в пакете.

Ответ 2

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

Если вы отправляете только одно выражение, технически вы можете отказаться от терминатора утверждения; в script, поскольку вы отправляете несколько заявлений, вам это нужно.

На практике всегда включайте терминатор, даже если вы просто отправляете один оператор в базу данных.

Изменить: в ответ на те, кто говорит, что терминаторы терминалов не требуются [конкретной СУБД], хотя это может быть правдой, они требуются стандартом ANSI SQL. Во всех программах, если мы можем придерживаться стандарта без потери функциональности, мы должны, потому что тогда ни наш код, ни наши привычки не привязаны к одному собственному вендору.

С некоторыми компиляторами C возможно иметь основной возврат void, хотя стандарт требует, чтобы main возвращал int. Но это делает наш код и нас самих менее переносимыми.

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

Ответ 3

В SQL2008 BOL они говорят, что в следующих выпусках будут нужны точки с запятой. Поэтому всегда используйте его.

Ссылка:

Ответ 4

Если я прочитаю это правильно, будет необходимо использовать точки с запятой для завершения инструкций TSQL. http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx

EDIT: Я нашел плагин для SSMS 2008R2, который отформатирует ваш script и добавит точки с запятой. Я думаю, что он все еще в бета-версии, хотя...

http://www.tsqltidy.com/tsqltidySSMSAddin.aspx

EDIT: Я нашел еще лучший бесплатный инструмент/плагин под названием ApexSQL... http://www.apexsql.com/

Ответ 5

Вы должны использовать его.

Практика использования точки с запятой для завершения заявлений является стандартной и на самом деле является требованием     в нескольких других платформах баз данных. SQL Server требует точку с запятой только в частности     случаев, но в тех случаях, когда точка с запятой не требуется, использование одного не вызывает проблем.     Я настоятельно рекомендую вам принять практику завершения всех операторов с точкой с запятой.     Это не только улучшит читабельность вашего кода, но и в некоторых случаях может     сберегите некоторое горе. (Когда точка с запятой требуется и не указана, сообщение об ошибке SQL     Сервер производит не всегда очень ясно.)

И самое главное:

Документация SQL Server указывает на то, что не завершать инструкции T-SQL с     точка с запятой - устаревшая функция. Это означает, что долгосрочная цель - обеспечить соблюдение     точки с запятой в будущей версии продукта. Это еще одна причина попасть в     привычка прекращать все ваши заявления, даже если его в настоящее время не требуется.

Источник: Основы Microsoft SQL Server 2012 T-SQL от Itzik Ben-Gan.


Примером того, почему вы всегда должны использовать ;, являются следующие два запроса (скопированные из этого post):

BEGIN TRY
    BEGIN TRAN
    SELECT 1/0 AS CauseAnException
    COMMIT
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE()
    THROW
END CATCH

enter image description here

BEGIN TRY
    BEGIN TRAN
    SELECT 1/0 AS CauseAnException;
    COMMIT
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE();
    THROW
END CATCH

enter image description here

Ответ 6

Личное мнение: Используйте их только там, где они требуются. (См. Ответ TheTXI выше для нужного списка.)

Поскольку компилятор не требует их, вы можете их перевернуть, но почему? Компилятор не скажет вам, где вы его забыли, поэтому в итоге вы столкнетесь с непоследовательным использованием.

[Это мнение относится к SQL Server. Другие базы данных могут иметь более строгие требования. Если вы пишете SQL для работы в нескольких базах данных, ваши требования могут отличаться.]

tpdi, указанный выше, "в script, поскольку вы отправляете несколько заявлений, вам это нужно". Это на самом деле не правильно. Вы им не нужны.

PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional';
PRINT 'Semicolons are optional';

Вывод:

Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional

Ответ 7

Мне еще многое предстоит узнать о T-SQL, но при разработке кода для транзакции (и базировании кода на примерах из stackoverflow и других сайтов) я нашел случай, когда кажется, что точка с запятой требуется, и если она отсутствует, инструкция, похоже, вообще не выполняется, и ошибка не возникает. Это, похоже, не рассматривается ни в одном из приведенных выше ответов. (Это использовало MS SQL Server 2012.)

Как только я обработал транзакцию так, как я хотел, я решил поместить вокруг нее попытку, поэтому, если есть какие-то ошибки, они откатываются. Только после этого транзакция не была выполнена (SSMS подтверждает это при попытке закрыть окно с помощью приятного сообщения, предупреждающего вас о том, что есть незафиксированная транзакция.

Итак, это

COMMIT TRANSACTION 

вне блока BEGIN TRY/END TRY работал нормально, чтобы зафиксировать транзакцию, но внутри блока это должно быть

COMMIT TRANSACTION;

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

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

В противоположность этому, ROLLBACK TRANSACTION, похоже, работает одинаково хорошо в блоке BEGIN CATCH с точкой с запятой или без нее.

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

Ответ 8

Согласно Соглашения синтаксиса Transact-SQL (Transact-SQL) (MSDN)

Терминатор операторов Transact-SQL. Хотя точка с запятой не требуется для большинства операторов в этой версии SQL Server, она потребуется в будущей версии.

(также см. комментарий @gerryLowry)

Ответ 9

Похоже, что точки с запятой не должны использоваться в сочетании с операциями курсора: OPEN, FETCH, CLOSE и DEALLOCATE. Я просто потратил пару часов на это. Я внимательно посмотрел на BOL и заметил, что [;] не показан в синтаксисе для этих инструкций курсора!

Итак, у меня было: ОТКРЫТЬ mycursor; и это дало мне ошибку 16916.

Но: ОТКРЫТЬ mycursor работал.

Ответ 10

Точки с запятой не всегда работают в сложных операторах SELECT.

Сравните эти две разные версии тривиального оператора SELECT.

Код

DECLARE @Test varchar(35); 
SELECT @Test=
    (SELECT 
        (SELECT 
            (SELECT 'Semicolons do not always work fine.';););); 
SELECT @Test Test;

возвращает

Msg 102, Level 15, State 1, Line 5
Incorrect syntax near ';'.

Однако код

DECLARE @Test varchar(35)
SELECT @Test=
    (SELECT 
        (SELECT 
            (SELECT 'Semicolons do not always work fine.'))) 
SELECT @Test Test

возвращает

Test
-----------------------------------
Semicolons do not always work fine.

(1 row(s) affected)

Ответ 11

Я почему-то не смог ответить на @rab, поэтому мне нужно будет отправить ответ:

Я не знаю, какую версию SQL Server использовал rab, но точки с запятой отлично работают с курсорами в SQL Server 2005 и 2008.

Попробуйте следующее, чтобы понять, что я имею в виду:

DECLARE @tblSource TABLE ( CharCol VARCHAR(20) );

INSERT INTO @tblSource (CharCol)
VALUES ('First');
INSERT INTO @tblSource (CharCol)
VALUES ('Second');

DECLARE @text VARCHAR(20);

DECLARE csr CURSOR
LOCAL FAST_FORWARD
FOR 
SELECT CharCol
FROM @tblSource
ORDER BY CharCol;

OPEN csr;

FETCH NEXT FROM csr
INTO @text;

WHILE @@FETCH_STATUS = 0
BEGIN;            
    PRINT @text;

    FETCH NEXT FROM csr
    INTO @text;
END;

CLOSE csr;
DEALLOCATE csr;

Ответ 12

При использовании инструкции DISABLE или ENABLE TRIGGER в пакете, в которой есть другие операторы, оператор перед тем, как он должен заканчиваться точкой с запятой. В противном случае вы получите синтаксическую ошибку. Я разорвал волосы с этим... И потом, я наткнулся на эту статью MS Connect о том же. Он закрыт, как не будет исправлено.

см. здесь

Ответ 13

Примечание. Это отвечает на вопрос как написанный, но не проблема, как указано. Добавьте его сюда, так как люди будут его искать

Точка с запятой также используется до WITH в рекурсивных операторах CTE:

;WITH Numbers AS
(
    SELECT n = 1
    UNION ALL
    SELECT n + 1
    FROM Numbers
    WHERE n+1 <= 10
)
SELECT n
FROM Numbers

Этот запрос будет генерировать CTE, называемый Numbers, который состоит из целых чисел [1..10]. Это делается путем создания таблицы со значением только 1, а затем рекурсией, пока вы не достигнете 10.

Ответ 14

Если вам нравится получать случайные ошибки командного тайм-аута в SQLServer, оставьте в конце строки с запятой в конце строк CommandText.

Я не знаю, зарегистрировано ли это где угодно, или если это ошибка, но это происходит, и я узнал об этом из горького опыта.

У меня есть проверенные и воспроизводимые примеры с использованием SQLServer 2008.

aka → На практике всегда включайте терминатор, даже если вы просто отправляете один оператор в базу данных.