Проверяя некоторый код в Интернете и сценарии, сгенерированные SQL Server Management Studio, я заметил, что некоторые операторы заканчиваются точкой с запятой.
Так, когда я должен использовать это?
Проверяя некоторый код в Интернете и сценарии, сгенерированные SQL Server Management Studio, я заметил, что некоторые операторы заканчиваются точкой с запятой.
Так, когда я должен использовать это?
Ответы:
Из статьи SQLServerCentral.Com Кена Пауэрса:
Точка с запятой
Точка с запятой является оператором-терминатором. Он является частью стандарта ANSI SQL-92, но никогда не использовался в Transact-SQL. Действительно, можно годами кодировать T-SQL, не встречая точки с запятой.
использование
Есть две ситуации, в которых вы должны использовать точку с запятой. Первая ситуация, когда вы используете общее табличное выражение (CTE), и CTE не является первым оператором в пакете. Во втором случае вы выполняете оператор Service Broker, а оператор Service Broker не является первым оператором в пакете.
THROW
ли заявление Service Broker? Мы должны включить точку с запятой перед броском в этом примере:BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
MERGE
тоже например). Как упоминалось в других ответах, в стандарте ANSI они обязательны
По умолчанию операторы SQL заканчиваются точкой с запятой. Вы используете точку с запятой для завершения операторов, если только вы (редко) не устанавливаете новый терминатор операторов.
Если вы отправляете только один оператор, технически вы можете обойтись без терминатора оператора; в сценарии, когда вы отправляете более одного оператора, он вам нужен.
На практике всегда включайте терминатор, даже если вы просто отправляете один оператор в базу данных.
Изменить: в ответ на эти высказывания терминаторы операторов не требуются [конкретной СУБД], хотя это может быть правдой, они требуются стандартом ANSI SQL. Во всем программировании, если мы можем придерживаться Стандарта без потери функциональности, мы должны это делать, потому что тогда ни наш код, ни наши привычки не связаны с одним частным поставщиком.
С некоторыми компиляторами C возможно возвращение main return, даже если стандарт требует main для возврата int. Но это делает наш код и нас самих менее переносимыми.
Самая большая трудность в программировании - не изучение новых вещей, а отучивание от вредных привычек. В той степени, в которой мы можем избежать приобретения вредных привычек, это выигрыш для нас, для нашего кода и для всех, кто читает или использует наш код.
В SQL2008 BOL говорят, что в следующих выпусках будут нужны точки с запятой. Поэтому всегда используйте его.
Ссылка:
Вы должны использовать это.
Практика использования точки с запятой для завершения операторов является стандартной и фактически является требованием в некоторых других платформах баз данных. SQL Server требует точку с запятой только в определенных случаях, но в тех случаях, когда точка с запятой не требуется, ее использование не вызывает проблем. Я настоятельно рекомендую вам принять практику завершения всех утверждений точкой с запятой. Это не только улучшит читабельность вашего кода, но в некоторых случаях может сэкономить вам немного времени. (Когда точка с запятой требуется и не указана, сообщение об ошибке, выдаваемое SQL Server, не всегда ясно).
И самое главное:
Документация по 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
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException;
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
THROW
END CATCH
not using them
не рекомендуется, вы должны их использовать. Если нет, есть риск страдать в будущем. Если вы не планируете обновлять / переключать работу и всегда собираетесь работать с SQL Server 2000, вы в безопасности :-)
Incorrect syntax near 'THROW'.
к SQL Server 2008 (10.0.6241.0), который является версией, с которой мне приходится иметь дело на работе. Это работает, как показано в 2012 году. Меня убедили начать использовать точки с запятой из-за устаревания. Я не ожидаю, что это будет проблемой в 2008 году в большинстве случаев.
Если я правильно прочитал, для завершения операторов TSQL будет необходимо использовать точки с запятой. http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx
РЕДАКТИРОВАТЬ: Я нашел плагин для SSMS 2008R2, который отформатирует ваш скрипт и добавит точки с запятой. Я думаю, что это все еще в бета-версии, хотя ...
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
РЕДАКТИРОВАТЬ: я нашел еще лучший бесплатный инструмент / плагин под названием ApexSQL ... http://www.apexsql.com/
Личное мнение: используйте их только там, где они необходимы. (См. Ответ 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
Мне еще многое предстоит узнать о T-SQL, но при разработке некоторого кода для транзакции (и на основе кода на примерах из stackoverflow и других сайтов) я обнаружил случай, когда кажется, что точка с запятой требуется, и если она отсутствует, утверждение, кажется, не выполняется вообще, и никакой ошибки не возникает. Это, кажется, не охвачено ни в одном из приведенных выше ответов. (Это было с использованием MS SQL Server 2012.)
После того, как транзакция работала так, как я хотел, я решил использовать ее, чтобы попытаться откатить ее. Только после этого транзакция не была зафиксирована (SSMS подтверждает это при попытке закрыть окно с хорошим сообщением, предупреждающим вас о факте незафиксированной транзакции.
Так это
COMMIT TRANSACTION
вне блока BEGIN TRY / END TRY работал нормально для фиксации транзакции, но внутри блока это должно было быть
COMMIT TRANSACTION;
Обратите внимание, что нет ошибок или предупреждений, а также указаний на то, что транзакция по-прежнему не завершена, пока не будет предпринята попытка закрыть вкладку запроса.
К счастью, это вызывает такую огромную проблему, что сразу становится очевидно, что проблема есть. К сожалению, поскольку не сообщается об ошибке (синтаксис или иное), не сразу было понятно, в чем проблема.
В противоположность этому, ROLLBACK TRANSACTION одинаково хорошо работает в блоке BEGIN CATCH с точкой с запятой или без нее.
Возможно, в этом есть какая-то логика, но она кажется произвольной и «Алиса в стране чудес».
COMMIT TRANSACTION
принятие необязательного имени транзакции / точки сохранения (которое оно будет игнорировать). Без завершающей точки с запятой COMMIT TRANSACTION
можно использовать следующий символ, если он анализируется как идентификатор, что может радикально изменить семантику кода. Если это приводит к ошибке, CATCH
запуск может COMMIT
выполняться без выполнения. И наоборот, хотя ROLLBACK TRANSACTION
и принимает необязательный идентификатор, подобный этому, ошибка при разборе там, скорее всего, в любом случае приведет к откату транзакции.
Оказывается , что точка с запятой не должны использоваться в сочетании с курсором операций: OPEN
, FETCH
, CLOSE
и DEALLOCATE
. Я просто потратил пару часов на это. Я внимательно посмотрел на BOL и заметил, что [;] не отображается в синтаксисе для этих операторов курсора !!
Итак, у меня было:
OPEN mycursor;
и это дало мне ошибку 16916.
Но:
OPEN mycursor
работал.
В соответствии с синтаксическими соглашениями Transact-SQL (Transact-SQL) (MSDN)
Терминатор Transact-SQL. Хотя точка с запятой не требуется для большинства операторов в этой версии SQL Server, она потребуется в следующей версии.
(также см. комментарий @gerryLowry)
При использовании оператора DISABLE или ENABLE TRIGGER в пакете, в котором есть другие операторы, оператор непосредственно перед ним должен заканчиваться точкой с запятой. В противном случае вы получите синтаксическую ошибку. Я сорвал свои волосы с этого ... И потом я наткнулся на этот пункт MS Connect о том же. Он закрыт, так как не исправит.
смотрите здесь
Примечание: это отвечает на вопрос в письменном виде, но не на проблему, как указано. Добавляя это здесь, так как люди будут искать это
Точка с запятой также используется ранее 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.
Если вам нравится получать случайные ошибки Command Timeout в SQLServer, то оставьте точку с запятой в конце ваших строк CommandText.
Я не знаю, документировано ли это где-нибудь или это ошибка, но это происходит, и я узнал об этом из горького опыта.
У меня есть проверяемые и воспроизводимые примеры с использованием SQLServer 2008.
aka -> На практике всегда включайте терминатор, даже если вы просто отправляете один оператор в базу данных.
Точки с запятой не всегда работают в составных операторах 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)