Під час перевірки деякого коду в Інтернеті та сценаріїв, створених 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 закінчуються крапками з комою. Ви використовуєте крапку з комою для завершення операторів, якщо ви (рідко) встановлюєте новий термінатор операторів.
Якщо ви надсилаєте лише одне твердження, технічно ви можете не обійтися термінатором оператора; у сценарії, оскільки ви надсилаєте кілька заяв, вам це потрібно.
На практиці завжди включайте термінатор, навіть якщо ви просто надсилаєте одне повідомлення в базу даних.
Редагувати: у відповідь на ці вимоги термінатори висловлювань не вимагають [конкретного RDBMS], хоча це може бути правдою, вони вимагаються стандартом ANSI SQL. Якщо у всіх програмуваннях ми можемо дотримуватися стандарту без втрати функціональності, ми повинні, оскільки тоді ні наш код, ні наші звички не пов'язані з одним власником постачальника.
З деякими компіляторами C можлива наявність основної недійсної віддачі, хоча стандарт вимагає головного повернення int. Але це робить наш код і ми самі менш портативними.
Найбільша складність у ефективному програмуванні - це не вивчення нових речей, це відучування шкідливих звичок. Наскільки ми можемо уникнути набуття шкідливих звичок в першу чергу, це виграш для нас, для нашого коду та для всіх, хто читає чи використовує наш код.
У SQL2008 BOL кажуть, що в наступних випусках знадобляться крапки з комою. Тому завжди використовуйте його.
Довідка:
Ви повинні використовувати його.
Практика використання крапки з комою для завершення операторів є стандартною і фактично є вимогою у кількох інших платформах баз даних. SQL Server вимагає крапки з комою лише в окремих випадках, але у випадках, коли крапка з комою не потрібна, використання її не викликає проблем. Настійно рекомендую вам скористатися практикою завершення всіх операцій крапкою з комою. Це не тільки покращить читабельність вашого коду, але в деяких випадках може врятувати вам горе. (Коли потрібна крапка з комою та не вказана, повідомлення про помилку, яке виробляє SQL Server, не завжди є дуже зрозумілим.)
І найголовніше:
Документація на SQL Server вказує, що неприпинення операторів T-SQL крапкою з комою є застарілою функцією. Це означає, що довгостроковою метою є примусове використання крапки з комою в майбутній версії продукту. Це ще одна причина ввійти в звичку припиняти всі свої заяви, навіть там, де це наразі не потрібно.
Джерело: Основи T-SQL Microsoft SQL Server 2012 Іцік Бен-Ган.
Прикладом того, чому завжди потрібно використовувати, ;
є наступні два запити (скопійовані з цієї публікації ):
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
EDIT: Я знайшов плагін для SSMS 2008R2, який буде форматувати ваш сценарій і додавати крапки з комою. Я думаю, він все ще знаходиться в бета-версії ...
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
EDIT: Я знайшов ще кращий безкоштовний інструмент / плагін під назвою 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.
Якщо вам подобається отримувати випадкові помилки Timeout 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)