Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

';' at the beginning of TSQL statements

From time to time I see SQL Server statements that start with semicolon ';' like below

;WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
                                       ORDER BY ( SELECT 0)) RN
         FROM   #MyTable)
DELETE FROM cte
WHERE  RN > 1

The other example is ;THROW

Why exactly there is a ';' the beginning of TSQL statements

Update 1:

Please note that I am asking about ';' at the beginning of statements. This question is not duplicate of this one

When should I use semicolons in SQL Server?

Update 2:

@MartinSmith answer makes sense.

Just to make sure we have a complete answer for this post, consider this respected article:

http://www.sommarskog.se/error_handling/Part1.html#jumpTHROW

At this point you might be saying to yourself: he must be pulling my legs, did Microsoft really call the command ;THROW? Isn't it just THROW? True, if you look it up in Books Online, there is no leading semicolon. But the semicolon must be there. Officially, it is a terminator for the previous statement, but it is optional, and far from everyone uses semicolons to terminate their T‑SQL statements.

I agree with @MartinSmith answer, but it seems that the matter is being taken to some quite extreme levels.

Typically, in a stored procedure THROW is a statement by its own line. SQL developers simply don't just merge SQL lines like that and miss a semicolon.

To me, there is more chance people accidently drop a table than mixing 'THROW' statement with another line of TSQL

Is the case explained in the quote above something extreme and rare to happen? or I am missing a point here?

like image 372
Allan Xu Avatar asked Aug 07 '16 17:08

Allan Xu


People also ask

What does a SQL query statement begin with?

1. Start your query with the select statement. A select statement queries the database and retrieves selected data that match the specified criteria.

How do you get the first 5 letters in SQL?

SQL Server LEFT() Function The LEFT() function extracts a number of characters from a string (starting from left).

How do you get the first 3 letters of a string in SQL?

You can use LEN() or LENGTH()(in case of oracle sql) function to get the length of a column. SELECT LEN(column_name) FROM table_name; And you can use SUBSTRING or SUBSTR() function go get first three characters of a column. Save this answer.

What is like %% in SQL?

The LIKE operator is used in a WHERE clause to search for a specified pattern in a column. There are two wildcards often used in conjunction with the LIKE operator: The percent sign (%) represents zero, one, or multiple characters. The underscore sign (_) represents one, single character.


1 Answers

It is supposed to be after the statements not before them. But in most cases in TSQL the terminating semi colons on statements are currently optional in practice (though technically Not ending Transact-SQL statements with a semicolon is deprecated) and the presence of statement terminating semi colons is not enforced.

An exception is the MERGE statement (that does require a terminating semi colon) and also statements preceding WITH or THROW

So this is a somewhat defensive practice for answers on StackOverflow in case the OP (or future readers) pastes it into the middle of some existing batch that doesn't have the required semi colon on the preceding statement and then complains it doesn't work and they receive the following error.

Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.

In the case that the preceding statement is terminated with a semicolon the additional one does no harm. It just is treated as an empty statement.

This practice can itself cause problems though where the CTE is used in a context where multi statements are not valid. e.g. Inserting a semicolon before the WITH here would break it.

CREATE VIEW V1
AS
  WITH T(X)
       AS (SELECT 1)
  SELECT *
  FROM   T; 

Similarly for THROW blindly inserting a leading semi colon can cause problems too.

IF @i IS NULL
;THROW 50000, '@i IS NULL', 1;  

Incorrect syntax near ';'.

I have fixed the example you give in your question and changed it to

; 

--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
                                       ORDER BY ( SELECT 0)) RN
         FROM   #MyTable)
DELETE FROM cte
WHERE  RN > 1;
like image 153
Martin Smith Avatar answered Nov 16 '22 02:11

Martin Smith