Когда я должен использовать точки с запятой в SQL Server? - PullRequest
193 голосов
/ 02 апреля 2009

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

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

Ответы [ 13 ]

137 голосов
/ 02 апреля 2009

Из статьи SQLServerCentral.Com Кена Пауэрса:

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

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

Usage

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

71 голосов
/ 02 апреля 2009

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

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

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

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

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

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

24 голосов
/ 02 апреля 2009

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

Справка:

22 голосов
/ 13 августа 2013

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

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

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

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

14 голосов
/ 14 октября 2014

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

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

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

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

Источник: Microsoft SQL Server 2012 Основы T-SQL Ицик Бен-Ган.


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

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

9 голосов
/ 02 апреля 2009

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

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

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

Указанное выше tpdi: «в сценарии, когда вы отправляете более одного оператора, он вам нужен». Это на самом деле не правильно. Вам они не нужны.

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
3 голосов
/ 11 июня 2015

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

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

Итак, это

COMMIT TRANSACTION 

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

COMMIT TRANSACTION;

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

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

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

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

3 голосов
/ 23 сентября 2009

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

Итак, у меня было:

OPEN mycursor;

и это дало мне ошибку 16916.

Но:

OPEN mycursor

работал.

2 голосов
/ 26 августа 2015

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

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

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

0 голосов
/ 04 октября 2015

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...