Or: *What is not a T-SQL statement?*

Except to resolve ambiguity, T-SQL syntax does not require a semicolon to terminate a statement. Despite this, [Itzik Ben-Gan](http://www.sqlmag.com/blog/puzzled-by-t-sql-blog-15/tsql/semicolon-140706) recommends using a semicolon to terminate a T-SQL statement because it makes code cleaner, more readable, easier to maintain, and more portable.

I don't know a precise definition of what a valid T-SQL statement is, so I might be confused here. But as far as I know, a BEGIN...END block is a T-SQL statement, so should be terminated by a semicolon. For example:

```
IF OBJECT_ID('tempdb.dbo.#TempTable') IS NOT NULL
BEGIN
  DROP TABLE #TempTable;
END;

```

The code example in Microsoft's [BEGIN...END documentation](http://msdn.microsoft.com/en-us/library/ms190487.aspx) supports this conjecture:

```
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.
*/

```

Itzik Ben-Gan contradicts this in the code example of Excercise 1-1 of [T-SQL Fundamentals](http://www.sql.co.il/books/tsqlfund2008/9780735626010_MSSQLServer08T-SQLFundamentals_ch03.pdf):

```
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's [Transact-SQL Syntax Conventions](http://msdn.microsoft.com/en-us/library/ms177563.aspx) document states that the semicolon "will be required in a future version" of T-SQL.

Commenting on Microsoft's intention to require the semicolon in a future version of T-SQL, Itzik notes some exceptions that aren't supposed to be terminated:

> 
> So far it was a requirement to use a semicolon only in specific cases. Now it looks like the plan is to make it a required terminator for all\* T-SQL statements in some future version of SQL Server.
> 
> 
> (\*) Naturally there are cases that aren’t supposed to be terminated with a semicolon; those include (but are not limited to):
> 
> 
> * BEGIN
> * BEGIN TRAN
> * IF
> * ELSE
> * WHILE
> * BEGIN TRY
> * END TRY
> * BEGIN CATCH
> 
> 
> 

Itzik seems to be consistent with himself, but Microsoft itself does not follow his recommendations. Compare Microsoft's `BEGIN TRANSACTION;` and Itzik's `BEGIN TRAN` in the previous examples.

In the code I maintain, I have seen even the `BEGIN` keyword terminated by semicolon:

```
IF @HasWidget = 0x1
BEGIN;
  SELECT WidgetID
  FROM tbWidgets;
END;

```

I believe a T-SQL parser may consider the semicolon following the `BEGIN` keyword to terminate an empty statement rather than terminate the `BEGIN` keyword itself; I don't believe that `BEGIN` itself is a valid T-SQL statement.

This conjecture is supported by the fact that SQL Server 2008 successfully parses and executes the following query:

```
SELECT 0;;

```

It's so confusing because there is no widely available specification of the T-SQL language, like the [Java Language Specification](http://java.sun.com/docs/books/jls/) for Java, so nowhere is there a formal definition of a T-SQL statement.

Am I wrong? Does such a specification exist for T-SQL, and is it publicly available?

Otherwise, should just I believe what Itzik says?