Или: что не является выражением T-SQL?
За исключением устранения двусмысленности, синтаксис T-SQL не требует, чтобы точка с запятой завершала оператор. Несмотря на это, Itzik Ben-Gan рекомендует использовать точку с запятой, чтобы прервать инструкцию T-SQL, поскольку она делает код более чистым, более читаемым, более простым в обслуживании и более переносимым.
Я не знаю точное определение того, что такое действительный оператор T-SQL, поэтому я мог бы смутить здесь. Но, насколько мне известно, блок BEGIN... END является оператором T-SQL, поэтому его следует прервать точкой с запятой. Например:
IF OBJECT_ID('tempdb.dbo.#TempTable') IS NOT NULL
BEGIN
DROP TABLE #TempTable;
END;
Пример кода в Microsoft BEGIN... END документация поддерживает эту гипотезу:
USE AdventureWorks2008R2;
GO
BEGIN TRANSACTION;
GO
IF @@TRANCOUNT = 0
BEGIN
SELECT FirstName, MiddleName
FROM Person.Person WHERE LastName = 'Adams';
ROLLBACK TRANSACTION;
PRINT N'Rolling back the transaction two times would cause an error.';
END;
ROLLBACK TRANSACTION;
PRINT N'Rolled back the transaction.';
GO
/*
Rolled back the tranaction.
*/
Ицик Бен-Ган противоречит этому в примере кода Упражнения 1-1 Основы T-SQL:
SET NOCOUNT ON;
USE TSQLFundamentals2008;
IF OBJECT_ID('dbo.Nums', 'U') IS NOT NULL DROP TABLE dbo.Nums;
CREATE TABLE dbo.Nums(n INT NOT NULL PRIMARY KEY);
DECLARE @i AS INT = 1;
BEGIN TRAN
WHILE @i <= 100000
BEGIN
INSERT INTO dbo.Nums VALUES(@i);
SET @i = @i + 1;
END
COMMIT TRAN
SET NOCOUNT OFF;
Microsoft Соглашения о синтаксисе Transact-SQL указывает, что точка с запятой "потребуется в будущей версии" T-SQL.
Комментируя намерение Microsoft потребовать точку с запятой в будущей версии T-SQL, Itzik отмечает некоторые исключения, которые не должны быть прерваны:
До сих пор требовалось использовать точку с запятой только в определенных случаях. Теперь похоже, что план должен сделать его обязательным терминатором для всех * операторов T-SQL в некоторой будущей версии SQL Server.
(*) Естественно, существуют случаи, когда arent должен заканчиваться точкой с запятой; они включают (но не ограничиваются ими):
НАЧАТЬ
BEGIN TRAN
IF
ELSE
WHILE
BEGIN TRY
END TRY
BEGIN CATCH
Ицик, похоже, согласен с самим собой, но сама Microsoft не следует его рекомендациям. Сравните Microsoft BEGIN TRANSACTION;
и Itzik BEGIN TRAN
в предыдущих примерах.
В коде, который я поддерживаю, я видел даже ключевое слово BEGIN
, которое заканчивается точкой с запятой:
IF @HasWidget = 0x1
BEGIN;
SELECT WidgetID
FROM tbWidgets;
END;
Я считаю, что анализатор T-SQL может рассматривать точку с запятой, следующую за ключевым словом BEGIN
, чтобы завершить пустой оператор, а не прервать ключевое слово BEGIN
; Я не считаю, что BEGIN
сам по себе является допустимым выражением T-SQL.
Эта гипотеза подтверждается тем фактом, что SQL Server 2008 успешно анализирует и выполняет следующий запрос:
SELECT 0;;
Это настолько запутанно, потому что нет широко распространенной спецификации языка T-SQL, например Java Language Specification для Java, поэтому нигде не существует формального определения инструкция T-SQL.
Неужели я ошибаюсь? Существует ли такая спецификация для T-SQL и доступна ли она публично?
В противном случае, просто я верю, что говорит Ицик?