Sql-Server
為什麼 CTE 應該以分號開頭?
我只是在看StackOverflow上的一篇文章,其中 Aaron Bertrand 建議使用 CTE 而不是數字表,這是一種執行手頭任務的優雅方式。我的問題是,為什麼 CTE 的第一行以分號開頭?
;WITH n AS (SELECT TOP (10000) n FROM (SELECT n = ROW_NUMBER() OVER (ORDER BY s1.[object_id]) FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2 ) AS x ORDER BY n ) SELECT n FROM n ORDER BY n; -- look ma, no gaps!
這是為了確保 WITH 語句不會被解析為以前的
SELECT
或其他東西嗎?我在 SQL Server 2005 BOL 中沒有看到關於在 WITH 之前使用分號的內容。
我在這里或 StackOverflow 上發帖時總是這樣做,因為 for
WITH
- 因為關鍵字已重載 -前一個命令需要一個終止分號。如果我粘貼一個使用 CTE 的程式碼範例,不可避免地會有一些使用者將其粘貼到他們現有的程式碼中,而前面的語句將沒有分號。所以程式碼中斷了,我收到如下抱怨:你的程式碼壞了!我收到此錯誤消息:
Incorrect syntax near 'WITH'
…雖然我想相信人們在總是用分號結束他們的陳述方面變得更好,但我寧願先發製人,總是把它包括在內。有些人不喜歡它,但是
<shrug />
。您可以根據需要在有效語句之前或之後包含任意數量的分號。這是有效的:;;;;SELECT 1;;;;;;;;;;;;SELECT 2;;;;;;;;SELECT 3;;;;;
因此,在根據定義需要它的語句之前有一個額外的分號是沒有害處的。這樣做更安全,即使它不是那麼漂亮。
必須用奇怪的措辭才能理解這一點,但是自 SQL Server 2008 以來,實際上已棄用“不以分號結束有效語句”。因此,正如我在上面連結到的部落格文章中所描述的那樣,即使在以下情況下它不需要繞過錯誤,它應該在任何有效的地方使用。你可以在這裡看到這個(並且這個條目已經有多個版本):
- SQL Server 2016 中已棄用的數據庫引擎功能
(在此頁面中搜尋semicolon
)如果沒有異常,當然不會是 SQL Server。嘗試這個:
BEGIN TRY; SELECT 1/1; END TRY; BEGIN CATCH; SELECT 1/1; END CATCH;
這不是規則的唯一例外,但它是我發現最不直覺的例外。