2009-04-02 96 views
167

Trong khi kiểm tra một số mã trên web và tập lệnh được tạo bởi SQL Server Management Studio, tôi đã nhận thấy rằng một số câu lệnh được kết thúc bằng dấu chấm phẩy.Khi nào tôi nên sử dụng dấu chấm phẩy trong SQL Server?

Vì vậy, khi nào tôi nên sử dụng?

+20

** SQL Server 2008 R2 ** http://msdn.microsoft.com/en-us/library/ms177563.aspx "Quy ước cú pháp giao dịch-SQL (Giao dịch-SQL)" **; ** == Dấu kết thúc câu lệnh Transact-SQL. Mặc dù dấu chấm phẩy không bắt buộc đối với hầu hết các câu lệnh trong ** phiên bản này ** của SQL Server, * nó sẽ được yêu cầu trong một phiên bản tương lai *. – gerryLowry

Trả lời

121

Từ một SQLServerCentral.Com article bởi Ken Powers:

Các chấm phẩy

Nhân vật dấu chấm phẩy là một terminator tuyên bố. Nó là một phần của tiêu chuẩn ANSI SQL-92, nhưng không bao giờ được sử dụng trong Transact-SQL. Thật vậy, nó đã có thể mã T-SQL trong nhiều năm mà không bao giờ gặp phải một dấu chấm phẩy.

Cách sử dụng

Có hai tình huống mà bạn phải sử dụng dấu chấm phẩy. Tình huống đầu tiên là nơi bạn sử dụng một biểu thức bảng chung (CTE), và CTE không phải là câu lệnh đầu tiên trong lô. Thứ hai là nơi bạn phát hành một tuyên bố Nhà môi giới dịch vụ và tuyên bố của Nhà môi giới dịch vụ không phải là câu lệnh đầu tiên trong lô.

+7

Tuyên bố 'THROW' có phải là Nhà môi giới dịch vụ không?Chúng ta cần bao gồm dấu chấm phẩy trước khi ném vào ví dụ này: 'BEGIN; THROW @Error, 'FundingID không hợp lệ', 2; RETURN \t END' –

+0

Dường như họ về cơ bản khuyến khích sử dụng dấu chấm phẩy nói chung, bằng cách yêu cầu nó trước tất cả các loại câu lệnh mới đã được giới thiệu trong những năm gần đây. (Ví dụ 'MERGE'). Như đã đề cập trong các câu trả lời khác, trong tiêu chuẩn ANSI chúng được yêu cầu –

+2

@maurocam Tôi nghĩ rằng bạn đã đọc tài liệu không chính xác. Nếu bạn nhìn vào liên kết đó, nó nói "** Không ** kết thúc câu lệnh Transact-SQL với dấu chấm phẩy." không được chấp nhận. – Caltor

61

Theo mặc định, các câu lệnh SQL được chấm dứt bằng dấu chấm phẩy. Bạn sử dụng dấu chấm phẩy để chấm dứt các câu lệnh trừ khi bạn (hiếm khi) thiết lập một trình kết thúc câu lệnh mới.

Nếu bạn đang gửi chỉ một tuyên bố, về mặt kỹ thuật bạn có thể phân phối với người kết thúc câu lệnh; trong một kịch bản, khi bạn đang gửi nhiều hơn một câu lệnh, bạn cần nó.

Trong thực tế, luôn bao gồm trình kết thúc ngay cả khi bạn chỉ gửi một câu lệnh tới cơ sở dữ liệu.

Chỉnh sửa: để trả lời các thuật ngữ câu lệnh nói trên không được yêu cầu bởi [RDBMS cụ thể], trong khi điều đó có thể đúng, chúng được yêu cầu bởi tiêu chuẩn SQL ANSI. Trong tất cả các chương trình, nếu chúng ta có thể tuân thủ một tiêu chuẩn mà không mất chức năng, chúng ta nên, bởi vì sau đó không phải mã của chúng tôi hoặc thói quen của chúng tôi được gắn với một nhà cung cấp độc quyền.

Với một số trình biên dịch C, có thể có khoảng trống trả về chính, mặc dù tiêu chuẩn yêu cầu chính trả về int. Nhưng làm như vậy làm cho mã của chúng tôi, và bản thân chúng ta, ít cầm tay hơn.

Khó khăn lớn nhất trong lập trình có hiệu quả không phải là học hỏi những điều mới, nó đào tạo thói quen xấu. Trong phạm vi mà chúng ta có thể tránh được thói quen xấu ngay từ đầu, đó là một chiến thắng cho chúng tôi, cho mã của chúng tôi, và cho bất cứ ai đọc hoặc sử dụng mã của chúng tôi.

+1

Điều này không đúng khi nói rằng bạn cần dấu chấm phẩy khi gửi nhiều câu lệnh. – TheTXI

7

Ý kiến ​​cá nhân: Chỉ sử dụng chúng khi được yêu cầu. (Xem Câu trả lời của TheXI ở trên cho danh sách yêu cầu.)

Vì trình biên dịch không yêu cầu chúng, bạn có thể đặt tất cả, nhưng tại sao? Trình biên dịch sẽ không cho bạn biết nơi bạn đã quên một, vì vậy bạn sẽ kết thúc với việc sử dụng không nhất quán.

[Ý kiến ​​này dành riêng cho SQL Server. Các cơ sở dữ liệu khác có thể có các yêu cầu nghiêm ngặt hơn. Nếu bạn đang viết SQL để chạy trên nhiều cơ sở dữ liệu, các yêu cầu của bạn có thể thay đổi.]

tpdi đã nêu ở trên, "trong kịch bản, khi bạn gửi nhiều hơn một câu lệnh, bạn cần nó." Điều đó thực sự không chính xác. Bạn không cần chúng.

PRINT 'Semicolons are optional' 
PRINT 'Semicolons are optional' 
PRINT 'Semicolons are optional'; 
PRINT 'Semicolons are optional'; 

Output:

Semicolons are optional 
Semicolons are optional 
Semicolons are optional 
Semicolons are optional 
+1

Bạn nghĩ gì về cuộc thảo luận này? http://www.sqlservercentral.com/Forums/Topic636549-8-1.aspx (Yoy có thể sử dụng [email protected]: bugmenot nếu bạn không có tài khoản) –

+0

Tôi đánh giá cao việc bạn đã nêu rõ điều này là chỉ là ý kiến ​​của bạn, tuy nhiên tôi không nghĩ rằng nó làm cho một câu trả lời tốt bởi vì nó xung đột với cả hai tài liệu của Microsoft và tiêu chuẩn ANSI. Tôi nghĩ ý kiến ​​này sẽ tốt hơn trong một bình luận. (Không cố gắng để bash bạn, bạn hoàn toàn được hưởng ý kiến ​​của bạn về cách sử dụng nửa tràng!) – izzy

1

Dường như dấu chấm phẩy nên không được sử dụng kết hợp với thao tác con trỏ: OPEN, FETCH, CLOSE và DEALLOCATE. Tôi chỉ lãng phí một vài giờ với điều này. Tôi đã có một cái nhìn gần gũi về BOL và nhận thấy rằng [;] không được hiển thị trong cú pháp cho các câu lệnh con trỏ này !!

Vì vậy, tôi đã có: MỞ mycursor; và điều này đã cho tôi lỗi 16916.

Nhưng: MỞ mycursor hoạt động.

+1

Tôi không nghĩ rằng điều này là chính xác. BOL không nhất quán trong việc đề cập đến dấu chấm phẩy trên cú pháp câu lệnh, hãy xem ví dụ SELECT. Thêm vào đó tôi đã chứng kiến ​​OPEN someCursor; làm việc tốt, tương tự cho FETCH, CLOSE và DEALLOCATE ... –

0

Khi sử dụng câu lệnh DISABLE hoặc ENABLE TRIGGER trong một lô có các câu lệnh khác trong đó, câu lệnh ngay trước khi nó phải kết thúc bằng dấu chấm phẩy. Nếu không, bạn sẽ gặp lỗi cú pháp. Tôi xé tóc ra với cái này ... Và sau đó, tôi vấp phải vật phẩm MS Connect này về cùng một thứ. Nó đóng cửa như sẽ không sửa chữa.

thấy here

20

Nếu tôi đọc một cách chính xác, nó sẽ là một yêu cầu để sử dụng dấu chấm phẩy để kết thúc các câu lệnh TSQL. http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx

EDIT: Tôi đã tìm thấy trình cắm cho SSMS 2008R2 sẽ định dạng tập lệnh của bạn và thêm dấu chấm phẩy. Tôi nghĩ rằng nó vẫn còn trong phiên bản beta mặc dù ...

http://www.tsqltidy.com/tsqltidySSMSAddin.aspx

EDIT: Tôi tìm thấy một thậm chí tốt hơn miễn phí công cụ/plugin gọi ApexSQL ... http://www.apexsql.com/

+1

http://www.tsqltidy.com dường như không tồn tại nữa. –

0

phẩy không phải lúc nào làm việc trong hợp chất Câu lệnh SELECT.

So sánh hai phiên bản khác nhau của một câu lệnh SELECT phức hợp tầm thường.

DECLARE @Test varchar(35); 
SELECT @Test= 
    (SELECT 
     (SELECT 
      (SELECT 'Semicolons do not always work fine.';););); 
SELECT @Test Test; 

lợi nhuận

Msg 102, Level 15, State 1, Line 5 
Incorrect syntax near ';'. 

Tuy nhiên, mã

DECLARE @Test varchar(35) 
SELECT @Test= 
    (SELECT 
     (SELECT 
      (SELECT 'Semicolons do not always work fine.'))) 
SELECT @Test Test 

lợi nhuận

Test 
----------------------------------- 
Semicolons do not always work fine. 

(1 row(s) affected) 
+8

[Một năm sau]: Wow Tôi rất ngạc nhiên khi chưa có ai nhận xét về câu trả lời này! Tất nhiên nó sẽ không hoạt động, dấu chấm phẩy là dấu phân cách, vì vậy mã của bạn với dấu chấm phẩy là: 1- SELECT @ Test = (SELECT (SELECT (SELECT 'Dấu chấm phẩy không phải lúc nào cũng hoạt động tốt.'; - đây không phải là một tuyên bố chính xác 2-); - có thể là 3-); - một trong đó là 4-); - một trong đó là dấu chấm phẩy phải sau dấu ngoặc đơn – PhpLou

11

Bạn phải sử dụng.

Việc sử dụng dấu chấm phẩy để chấm dứt câu lệnh là tiêu chuẩn và thực tế là yêu cầu trong một số nền tảng cơ sở dữ liệu khác. SQL Server yêu cầu dấu chấm phẩy chỉ trong trường hợp cụ thể là — nhưng trong trường hợp không cần dấu chấm phẩy, việc sử dụng dấu chấm phẩy không gây ra sự cố. Tôi khuyên bạn nên áp dụng thực tiễn chấm dứt tất cả các câu lệnh bằng dấu chấm phẩy. Không chỉ làm điều này sẽ cải thiện khả năng đọc mã của bạn, nhưng trong một số trường hợp, nó có thể giúp bạn tiết kiệm một số đau buồn. (Khi một dấu chấm phẩy là cần thiết và không được chỉ định, SQL thông báo lỗi máy chủ sản xuất không phải lúc nào cũng rất rõ ràng.)

Và quan trọng nhất:

Tài liệu SQL Server chỉ ra rằng không phải chấm dứt T Các câu lệnh SQL với dấu chấm phẩy là một tính năng không được chấp nhận. Điều này có nghĩa là mục tiêu dài hạn là thực thi sử dụng dấu chấm phẩy trong phiên bản tương lai của sản phẩm. Đó là một lý do nữa để tham gia vào thói quen chấm dứt tất cả các tuyên bố của bạn, ngay cả khi hiện tại không bắt buộc.

Nguồn: Microsoft SQL Server 2012 Nguyên tắc cơ bản về T-SQL bởi Itzik Ben-Gan.


Một ví dụ về lý do tại sao bạn luôn phải sử dụng ; là hai câu hỏi sau đây (sao chép từ post này):

BEGIN TRY 
    BEGIN TRAN 
    SELECT 1/0 AS CauseAnException 
    COMMIT 
END TRY 
BEGIN CATCH 
    SELECT ERROR_MESSAGE() 
    THROW 
END CATCH 

enter image description here

BEGIN TRY 
    BEGIN TRAN 
    SELECT 1/0 AS CauseAnException; 
    COMMIT 
END TRY 
BEGIN CATCH 
    SELECT ERROR_MESSAGE(); 
    THROW 
END CATCH 

enter image description here

+3

Điều này có vẻ là một đối số mạnh mẽ rằng bạn * nên * sử dụng dấu chấm phẩy (được sao lưu bằng dấu ngoặc kép), nhưng chỉ có một trường hợp duy nhất có dấu * phải *. – Gregor

+2

@Gregor, nếu được thông báo rằng việc sử dụng dấu chấm phẩy là phải và 'không sử dụng chúng 'là kỹ thuật không được chấp nhận, bạn nên sử dụng chúng. Nếu không, có nguy cơ phải chịu đựng trong tương lai. Nếu bạn không có kế hoạch nâng cấp/chuyển đổi công việc và luôn làm việc với SQL Server 2000, bạn an toàn :-) – gotqn

+3

Phải, * nên *, tôi đồng ý. Nhưng dòng đầu tiên của bạn trả lời nhấn mạnh ** phải **, mà không phải là trường hợp --- ít nhất là chưa. – Gregor

2

tôi vẫn có rất nhiều điều để học về T-SQL, nhưng trong khi làm việc một số mã cho một giao dịch (và mã cơ sở trên các ví dụ từ stackoverflow và các trang khác), tôi đã tìm thấy một trường hợp có vẻ như dấu chấm phẩy là bắt buộc và nếu nó bị thiếu, câu lệnh dường như không thực thi và không có lỗi nào được nêu ra. Điều này dường như không được đề cập đến trong bất kỳ câu trả lời nào ở trên. (Điều này đã được sử dụng MS SQL Server 2012.)

Khi tôi đã có giao dịch hoạt động theo cách mình muốn, tôi quyết định đặt thử xung quanh để nếu có bất kỳ lỗi nào được cuộn lại.Chỉ sau khi làm điều này, giao dịch đã không cam kết (SSMS xác nhận điều này khi cố gắng để đóng cửa sổ với một thông điệp đẹp cảnh báo bạn đến một thực tế rằng có một giao dịch không bị giam.

Vì vậy, đây

COMMIT TRANSACTION 

ngoài một BEGIN TRY khối/END TRY làm việc tốt để thực hiện các giao dịch, nhưng bên trong block nó phải được

COMMIT TRANSACTION; 

Lưu ý không có lỗi hoặc cảnh báo được cung cấp và không có dấu hiệu cho thấy các giao dịch vẫn còn bị giam cho đến khi cố gắng để đóng cái que ry tab.

May mắn thay điều này gây ra một vấn đề lớn đến nỗi ngay lập tức rõ ràng là có vấn đề. Thật không may vì không có lỗi (cú pháp hoặc cách khác) được báo cáo là nó không rõ ràng vấn đề là gì.

Ngược lại, giao dịch ROLLBACK dường như hoạt động tốt như nhau trong khối BEGIN CATCH có hoặc không có dấu chấm phẩy.

Có thể có một số logic cho điều này nhưng nó cảm thấy tùy ý và Alice-in-Wonderland-ish.

0

Lưu ý: Câu hỏi này trả lời câu hỏi dưới dạng văn bản chứ không phải vấn đề như đã nêu. Thêm nó ở đây, vì mọi người sẽ tìm kiếm nó

chấm phẩy cũng được sử dụng trước khi WITH trong báo cáo CTE đệ quy:

;WITH Numbers AS 
(
    SELECT n = 1 
    UNION ALL 
    SELECT n + 1 
    FROM Numbers 
    WHERE n+1 <= 10 
) 
SELECT n 
FROM Numbers 

Truy vấn này sẽ tạo ra một CTE gọi số đó bao gồm các số nguyên [1 .. 10]. Nó được thực hiện bằng cách tạo ra một bảng với giá trị 1 chỉ, và sau đó recursing cho đến khi bạn đạt 10

+7

Về mặt kỹ thuật không phải 'trước khi có', nhưng sau bất kỳ điều gì xảy ra trước đây. Nếu có là câu lệnh đầu tiên trong lô, không cần dấu chấm phẩy. –

2

Theo Transact-SQL Syntax Conventions (Transact-SQL) (MSDN)

Transact-SQL tuyên bố terminator. Mặc dù dấu chấm phẩy không bắt buộc đối với hầu hết các câu lệnh trong phiên bản SQL Server này, nó sẽ được yêu cầu trong một phiên bản tương lai.

(cũng thấy @gerryLowry 's bình luận)

0

Nếu bạn thích nhận được ngẫu nhiên lệnh Timeout sai sót trong SQLServer sau đó rời khỏi dấu chấm phẩy ở cuối chuỗi CommandText của bạn.

Tôi không biết nếu điều này được ghi lại ở bất cứ nơi nào hoặc nếu nó là một lỗi, nhưng nó xảy ra và tôi đã học được điều này từ kinh nghiệm cay đắng.

Tôi có ví dụ có thể kiểm chứng và tái sản xuất sử dụng SQLServer 2008.

aka ->Trong thực tế, luôn luôn bao gồm terminator ngay cả khi bạn chỉ cần gửi một tuyên bố cơ sở dữ liệu.

Các vấn đề liên quan