title: When should I not use a semicolon?
body: <p>Or: <em>What is not a T-SQL statement?</em></p>
  <p>Except to resolve ambiguity, T-SQL syntax does not require a semicolon to terminate a statement. Despite this, <a href="http://www.sqlmag.com/blog/puzzled-by-t-sql-blog-15/tsql/semicolon-140706" rel="noreferrer">Itzik Ben-Gan</a> recommends using a semicolon to terminate a T-SQL statement because it makes code cleaner, more readable, easier to maintain, and more portable.</p>
  <p>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:</p>
  <pre><code>IF OBJECT_ID('tempdb.dbo.#TempTable') IS NOT NULL
  BEGIN
    DROP TABLE #TempTable;
  END;
  </code></pre>
  <p>The code example in Microsoft's <a href="http://msdn.microsoft.com/en-us/library/ms190487.aspx" rel="noreferrer">BEGIN...END documentation</a> supports this conjecture:</p>
  <pre><code>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.
  */
  </code></pre>
  <p>Itzik Ben-Gan contradicts this in the code example of Excercise 1-1 of <a href="http://www.sql.co.il/books/tsqlfund2008/9780735626010_MSSQLServer08T-SQLFundamentals_ch03.pdf" rel="noreferrer">T-SQL Fundamentals</a>:</p>
  <pre><code>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 &lt;= 100000
    BEGIN
      INSERT INTO dbo.Nums VALUES(@i);
      SET @i = @i + 1;
    END
  COMMIT TRAN
  SET NOCOUNT OFF;
  </code></pre>
  <p>Microsoft's <a href="http://msdn.microsoft.com/en-us/library/ms177563.aspx" rel="noreferrer">Transact-SQL Syntax Conventions</a> document states that the semicolon &quot;will be required in a future version&quot; of T-SQL.</p>
  <p>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:</p>
  <blockquote>
  <p>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.</p>
  <p>(*) Naturally there are cases that aren’t supposed to be terminated with a semicolon; those include (but are not limited to):</p>
  <ul>
  <li><p>BEGIN</p>
  </li>
  <li><p>BEGIN TRAN</p>
  </li>
  <li><p>IF</p>
  </li>
  <li><p>ELSE</p>
  </li>
  <li><p>WHILE</p>
  </li>
  <li><p>BEGIN TRY</p>
  </li>
  <li><p>END TRY</p>
  </li>
  <li><p>BEGIN CATCH</p>
  </li>
  </ul>
  </blockquote>
  <p>Itzik seems to be consistent with himself, but Microsoft itself does not follow his recommendations. Compare Microsoft's <code>BEGIN TRANSACTION;</code> and Itzik's <code>BEGIN TRAN</code> in the previous examples.</p>
  <p>In the code I maintain, I have seen even the <code>BEGIN</code> keyword terminated by semicolon:</p>
  <pre><code>IF @HasWidget = 0x1
  BEGIN;
    SELECT WidgetID
    FROM tbWidgets;
  END;
  </code></pre>
  <p>I believe a T-SQL parser may consider the semicolon following the <code>BEGIN</code> keyword to terminate an empty statement rather than terminate the <code>BEGIN</code> keyword itself; I don't believe that <code>BEGIN</code> itself is a valid T-SQL statement.</p>
  <p>This conjecture is supported by the fact that SQL Server 2008 successfully parses and executes the following query:</p>
  <pre><code>SELECT 0;;
  </code></pre>
  <p>It's so confusing because there is no widely available specification of the T-SQL language, like the <a href="http://java.sun.com/docs/books/jls/" rel="noreferrer">Java Language Specification</a> for Java, so nowhere is there a formal definition of a T-SQL statement.</p>
  <p>Am I wrong? Does such a specification exist for T-SQL, and is it publicly available?</p>
  <p>Otherwise, should just I believe what Itzik says?</p>