Tại sao CTE nên bắt đầu bằng dấu chấm phẩy?


13

Tôi chỉ nhìn vào một bài đăng trên StackOverflow nơi Aaron Bertrand đề xuất sử dụng CTE thay vì bảng số, đây là một cách thanh lịch để thực hiện nhiệm vụ trong tay. Câu hỏi của tôi là, tại sao dòng đầu tiên của CTE bắt đầu bằng dấu chấm phẩy?

;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!

Đây có phải là để đảm bảo câu lệnh VỚI không bị phân tích cú pháp thành trước đó SELECThay không? Tôi không thấy gì trong SQL Server 2005 BOL về việc sử dụng dấu chấm phẩy trước chữ CÓ.


Câu trả lời:


25

Tôi luôn luôn làm điều đó khi đăng ở đây hoặc trên StackOverflow bởi vì WITH- vì từ khóa bị quá tải - lệnh trước đó yêu cầu một dấu chấm phẩy chấm dứt. Nếu tôi dán một mẫu mã sử dụng CTE, chắc chắn một số người dùng sẽ dán nó vào mã hiện có của họ và câu lệnh trước đó sẽ không có dấu chấm phẩy. Vì vậy, mã bị phá vỡ, và tôi nhận được khiếu nại như:

Mã của bạn đã phá vỡ! Tôi nhận được thông báo lỗi này:

Incorrect syntax near 'WITH'...

Mặc dù tôi muốn tin rằng mọi người đang trở nên tốt hơn về việc luôn chấm dứt các tuyên bố của họ bằng dấu chấm phẩy , tôi thà làm ồn trước tiếng ồn và luôn luôn bao gồm nó. Một số người không thích nó, nhưng <shrug />. Bạn có thể bao gồm nhiều dấu chấm phẩy trước hoặc sau một tuyên bố hợp lệ như bạn muốn. Điều này hợp lệ:

;;;;SELECT 1;;;;;;;;;;;;SELECT 2;;;;;;;;SELECT 3;;;;;

Vì vậy, không có hại trong việc có thêm một dấu chấm phẩy trước một tuyên bố mà theo định nghĩa đòi hỏi nó. Làm như vậy sẽ an toàn hơn ngay cả khi nó không quá đẹp.

Nó phải được diễn đạt một cách kỳ lạ để hiểu ý, nhưng "không kết thúc một tuyên bố hợp lệ bằng dấu chấm phẩy" thực sự không được chấp nhận kể từ SQL Server 2008. Vì vậy, như tôi mô tả trong bài đăng trên blog tôi liên kết đến ở trên, ngay cả trong trường hợp không bắt buộc phải bỏ qua lỗi, nó nên được sử dụng bất cứ khi nào hợp lệ. Bạn có thể thấy điều này ở đây:

http://msdn.microsoft.com/en-us/l Library / ms143729.aspx

(Tìm kiếm trang cuối cùng cho "dấu chấm phẩy")

Tất nhiên, đó sẽ không phải là SQL Server nếu không có ngoại lệ. Thử đi:

BEGIN TRY;
  SELECT 1/1;
END TRY;
BEGIN CATCH;
  SELECT 1/1;
END CATCH;

Đó không phải là ngoại lệ duy nhất cho quy tắc nhưng đó là điều tôi thấy không trực quan nhất.


1
Vào năm 2012, ngay cả tôi cũng nhận được thông báo lỗi tương tự, nhưng chỉ vì dấu chấm phẩy sau END TRY: i.stack.imgur.com/rc6dw.png - nếu tôi xóa dấu chấm phẩy đó, mọi thứ sẽ hoạt động.
Aaron Bertrand

Tôi nghĩ rằng bạn không thể đặt dấu chấm phẩy trước đây BEGIN CATCHđơn giản vì nó là một phần của một câu lệnh ghép được giới thiệu cùng BEGIN TRY. Nó giống như đặt một dấu chấm phẩy trước một IFtuyên bố ELSE.
Andriy M

@AndriyM Tôi đã có một cuộc trò chuyện chi tiết hơn nhiều về các quy tắc ở đây. Tôi đã đề cập đến nó bởi vì đó là một bất ngờ cho tất cả những người đi qua nó, không phải vì tôi không hiểu lý do. :-)
Aaron Bertrand

10

Điều này là để đảm bảo rằng nó không được bao gồm trong bất kỳ câu lệnh nào trước đây vì WITHcó thể phục vụ nhiều mục đích khác nhau trong T-SQL.

Nếu đó là tuyên bố đầu tiên trong đợt, tôi không nghĩ bạn cần nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.