Khi kiểm tra một số mã trên web và các 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.
Vậy khi nào tôi nên sử dụng nó?
Khi kiểm tra một số mã trên web và các 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.
Vậy khi nào tôi nên sử dụng nó?
Câu trả lời:
Từ một bài viết SQLServerCentral.Com của Ken Powers:
Dấu chấm phẩy
Ký tự dấu chấm phẩy là một dấu kết thúc câu lệnh. 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, có thể mã T-SQL trong nhiều năm mà không gặp phải dấu chấm phẩy.
Sử dụng
Có hai tình huống 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 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 đưa ra câu lệnh Nhà môi giới dịch vụ và câu lệnh Nhà môi giới dịch vụ không phải là câu lệnh đầu tiên trong lô.
THROW
một tuyên bố môi giới dịch vụ? Chúng ta cần bao gồm một dấu chấm phẩy trước khi ném trong ví dụ này:BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
MERGE
quá ví dụ). 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
Theo mặc định, các câu lệnh SQL được kết thúc 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 dấu kết thúc câu lệnh mới.
Nếu bạn chỉ gửi một câu lệnh, về mặt kỹ thuật, bạn có thể phân phối với bộ kết thúc câu lệnh; trong một tập lệnh, khi bạn 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 dấu kết thúc ngay cả khi bạn chỉ gửi một câu lệnh đến cơ sở dữ liệu.
Chỉnh sửa: để đáp lại những câu kết thúc câu lệnh 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ủ Tiêu chuẩn mà không mất chức năng, thì chúng ta nên, bởi vì sau đó, cả mã và thói quen của chúng ta không bị ràng buộc 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 phải trả về int. Nhưng làm như vậy làm cho mã của chúng ta, và chính chúng ta, ít di động hơn.
Khó khăn lớn nhất trong lập trình một cách hiệu quả là không học được những điều mới, đó là bỏ thói quen xấu. Trong phạm vi mà chúng ta có thể tránh mắc phải những thói quen xấu ngay từ đầu, đó là một chiến thắng cho chúng ta, cho mã của chúng ta và cho bất kỳ ai đọc hoặc sử dụng mã của chúng ta.
Trong SQL2008 BOL, họ nói rằng trong các bản phát hành tiếp theo, dấu chấm phẩy sẽ được yêu cầu. Do đó, luôn luôn sử dụng nó.
Tài liệu tham khảo:
Bạn phải sử dụng nó.
Việc sử dụng dấu chấm phẩy để chấm dứt các câu lệnh là tiêu chuẩn và trên thực tế là một yêu cầu trong một số nền tảng cơ sở dữ liệu khác. SQL Server chỉ yêu cầu dấu chấm phẩy trong các trường hợp cụ thể, nhưng trong trường hợp không cần dấu chấm phẩy, sử dụng một dấu chấm không gây ra vấn đề. Tôi thực sự khuyên bạn nên áp dụng thực hành chấm dứt tất cả các câu 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, mà 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 cần có dấu chấm phẩy và không được chỉ định, thông báo lỗi SQL Server tạo ra không phải lúc nào cũng rõ ràng.)
Và quan trọng nhất:
Tài liệu SQL Server chỉ ra rằng việc không chấm dứt các câu lệnh T-SQL bằng dấu chấm phẩy là một tính năng không dùng nữa. Điều này có nghĩa là mục tiêu dài hạn là bắt buộc 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 để có thói quen chấm dứt tất cả các tuyên bố của bạn, ngay cả khi điều đó hiện không bắt buộc.
Nguồn: Nguyên tắc cơ bản về T-SQL của Microsoft SQL Server 2012 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 truy vấn sau (được sao chép từ bài đăng này ):
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
THROW
END CATCH
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException;
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
THROW
END CATCH
not using them
kỹ thuật bắt buộc và không dùng nữa, bạn nên sử dụng chúng. Nếu không, có một rủi ro phải chịu 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 hoạt động với SQL Server 2000, bạn sẽ an toàn :-)
Incorrect syntax near 'THROW'.
đến SQL Server 2008 (10.0.6241.0), đây là phiên bản tôi phải xử lý trong công việc. Nó hoạt động như được hiển thị vào năm 2012. Tôi đã bị thuyết phục bắt đầu sử dụng dấu chấm phẩy vì sự phản đối. Tôi không hy vọng nó sẽ là một vấn đề vào năm 2008 hầu hết thời gian.
Nếu tôi đọc chính xác, đây 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/l Library / ms143729% 28v = sql.120% 29.aspx
EDIT: Tôi đã tìm thấy một 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 đang trong giai đoạn thử nghiệm ...
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
EDIT: Tôi đã tìm thấy một công cụ / plugin miễn phí thậm chí còn tốt hơn có tên là ApexSQL ... http://www.apexsql.com/
Ý kiến cá nhân: sử dụng chúng khi cần thiết. (Xem câu trả lời của TheTXI ở trên để biết danh sách bắt buộc.)
Vì trình biên dịch không yêu cầu chúng, bạn có thể đặt chúng khắp nơi, 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, 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 là 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ói ở trên, "trong một kịch bản, vì bạn đang gửi nhiều hơn một câu lệnh, bạn cần nó." Điều đó thực sự không đúng. Bạn không cần chúng.
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional';
PRINT 'Semicolons are optional';
Đầu ra:
Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional
Tôi vẫn còn nhiều điều để tìm hiểu về T-SQL, nhưng khi thực hiện một số mã cho giao dịch (và dựa trên các ví dụ từ stackoverflow và các trang web khác) Tôi đã tìm thấy một trường hợp có vẻ như là dấu chấm phẩy và nếu nó bị thiếu, câu lệnh dường như không thực thi chút nào và không có lỗi nào được nêu ra. Điều này dường như không được đề cập trong bất kỳ câu trả lời nào ở trên. (Điều này đã sử dụng MS SQL Server 2012.)
Khi tôi có giao dịch hoạt động theo cách tôi muốn, tôi quyết định đặt thử bắt xung quanh nó để nếu có bất kỳ lỗi nào, nó sẽ được khôi phục. Chỉ sau khi thực hiện việc này, giao dịch không được 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 tốt đẹp cảnh báo bạn về thực tế rằng có một giao dịch không được cam kết.
Vậy đây
COMMIT TRANSACTION
bên ngoài khối BEGIN TRY / END TRY hoạt động tốt để thực hiện giao dịch, nhưng bên trong khối đó phải là
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 nào cho thấy giao dịch vẫn không được cam kết cho đến khi cố gắng đóng tab truy vấn.
May mắn là điều này gây ra một vấn đề lớn như vậy mà rõ ràng là có một 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 nên không rõ vấn đề là gì ngay lập tức.
Trái ngược với khôn ngoan, 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 độc đoán và Alice-in-Wonderland-ish.
COMMIT TRANSACTION
chấp nhận một tên giao dịch / lưu điểm tùy chọn (mà nó sẽ bỏ qua). Nếu không có dấu chấm phẩy kết thúc, COMMIT TRANSACTION
có thể ăn ký hiệu tiếp theo nếu nó phân tích cú pháp như một định danh, có thể thay đổi hoàn toàn ngữ nghĩa của mã. Nếu điều này sau đó dẫn đến một lỗi, CATCH
có thể kích hoạt mà không COMMIT
bao giờ được thực hiện. Ngược lại, mặc dù ROLLBACK TRANSACTION
cũng chấp nhận một mã định danh tùy chọn như thế này, một lỗi trong phân tích cú pháp có nhiều khả năng dẫn đến giao dịch bị quay trở lại.
Dường như dấu chấm phẩy không nên được sử dụng kết hợp với các hoạt động 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 đã xem xét kỹ 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ó:
OPEN mycursor;
và điều này đã cho tôi lỗi 16916.
Nhưng:
OPEN mycursor
đã làm việc.
Theo Công ước cú pháp Transact-SQL (Transact-SQL) (MSDN)
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 SQL Server này, nhưng nó sẽ được yêu cầu trong phiên bản tương lai.
(cũng xem bình luận của @gerryLowry)
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 bằng cái này ... Và sau đó, tôi tình cờ thấy mục MS Connect này về điều tương tự. Nó được đóng lại vì sẽ không sửa chữa.
xem ở đây
Lưu ý: Điều này trả lời câu hỏi như bằng văn bản, nhưng không phải là vấn đề như đã nêu. Thêm nó ở đây, vì mọi người sẽ tìm kiếm nó
Dấu chấm phẩy cũng được sử dụng trước đây WITH
trong các câu lệnh 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 được gọi là Số bao gồm các số nguyên [1..10]. Nó được thực hiện bằng cách tạo một bảng chỉ có giá trị 1, và sau đó đệ quy cho đến khi bạn đạt 10.
Nếu bạn muốn nhận được lỗi Hết thời gian lệnh ngẫu nhiên trong SQLServer thì hãy bỏ 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ứ đâu hoặc nếu đó 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ó các ví dụ có thể kiểm chứng và tái sản xuất bằng SQLServer 2008.
aka -> Trong thực tế, luôn bao gồm dấu kết thúc ngay cả khi bạn chỉ gửi một câu lệnh đến cơ sở dữ liệu.
Dấu chấm phẩy không phải lúc nào cũng hoạt động trong các câu lệnh CHỌN ghép.
So sánh hai phiên bản khác nhau của một câu lệnh CHỌN hợp chất tầm thường.
Mật mã
DECLARE @Test varchar(35);
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.';);););
SELECT @Test Test;
trả lại
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
trả lại
Test
-----------------------------------
Semicolons do not always work fine.
(1 row(s) affected)