Trước khi trả lời khi nào nên sử dụng nó và tại sao, điều đầu tiên là hiểu chính xác GO
nó là gì và không phải là gì.
Từ khóa GO
được SQL Server Management Studio và SQLCMD sử dụng để biểu thị một điều và chỉ một điều: Kết thúc một loạt các câu lệnh. Trên thực tế, bạn thậm chí có thể thay đổi những gì bạn sử dụng để chấm dứt các đợt thành một thứ khác ngoài "GO":
Ảnh chụp màn hình ở trên là một tùy chọn trong SSMS có thể định cấu hình.
Nhưng một lô là gì ?? Tài liệu tham khảo BOL này nói rằng nó tốt nhất:
Một lô là một nhóm gồm một hoặc nhiều câu lệnh Transact-SQL được gửi cùng lúc từ một ứng dụng đến SQL Server để thực thi.
Đơn giản như thế. Đó chỉ là một cách tùy chỉnh một ứng dụng (vâng ... một ứng dụng) gửi các câu lệnh đến SQL Server. Chúng ta hãy xem một ví dụ về ứng dụng này. Tôi sẽ sử dụng PowerShell để bắt chước những gì một ứng dụng sẽ làm để gửi các câu lệnh và các đợt tới SQL Server:
$ConnectionString = "data source = SomeSQLInstance; initial catalog = AdventureWorks2012; trusted_connection = true; application name = BatchTesting;"
try {
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection($ConnectionString)
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.Connection = $SqlConnection
# first batch of statements
#
$SqlCmd.CommandText = "
select * from humanresources.department where departmentid = 1;
select * from humanresources.department where departmentid = 2;
select * from humanresources.department where departmentid = 3;
select * from humanresources.department where departmentid = 4;"
# execute the first batch
#
$SqlConnection.Open()
$SqlCmd.ExecuteNonQuery()
$SqlConnection.Close()
# second batch of statements
#
$SqlCmd.CommandText = "
select * from humanresources.department where departmentid = 5;
select * from humanresources.department where departmentid = 6;
select * from humanresources.department where departmentid = 7;
select * from humanresources.department where departmentid = 8;"
# execute the second batch
#
$SqlConnection.Open()
$SqlCmd.ExecuteNonQuery()
$SqlConnection.Close()
}
catch {
$SqlCmd.Dispose()
$SqlConnection.Dispose()
Write-Error $_.Exception
}
Các ý kiến cho đi, nhưng bạn có thể thấy ở trên rằng chúng tôi đang lập trình gửi hai lô tới SQL Server. Hãy xác minh rằng, mặc dù. Lựa chọn của tôi ở đây là sử dụng Sự kiện mở rộng:
create event session BatchTesting
on server
add event sqlserver.sql_batch_starting
(
set
collect_batch_text = 1
where
(
sqlserver.client_app_name = N'BatchTesting'
)
),
add event sqlserver.sql_batch_completed
(
set
collect_batch_text = 1
where
(
sqlserver.client_app_name = N'BatchTesting'
)
),
add event sqlserver.sql_statement_starting
(
set
collect_statement = 1
where
(
sqlserver.client_app_name = N'BatchTesting'
)
),
add event sqlserver.sql_statement_completed
(
set
collect_statement = 1
where
(
sqlserver.client_app_name = N'BatchTesting'
)
)
add target package0.event_file
(
set
filename = N'<MyXelLocation>\BatchTesting.xel'
);
go
alter event session BatchTesting
on server
state = start;
go
Tất cả phiên XEvents này đang thực hiện là ghi lại các câu lệnh và lô bắt đầu và hoàn thành từ một ứng dụng có tên "BatchTesting"
(nếu bạn nhận thấy chuỗi kết nối của tôi trong ví dụ mã PowerShell của tôi, đó là cách nhanh chóng để xem xét một người khởi tạo cụ thể các sự kiện bằng cách sử dụng "ứng dụng" tên "tham số chuỗi kết nối và lọc ra khỏi đó).
Sau khi tôi thực thi mã PowerShell để gửi các lô và báo cáo đó, tôi thấy các kết quả sau:
Như bạn có thể thấy từ ảnh chụp màn hình, rõ ràng cách các câu lệnh được chia thành hai lô khác nhau, cũng được thể hiện rõ bằng các phương tiện chúng ta sử dụng để gọi các đợt. Và nếu chúng ta nhìn vào batch_text
lần xuất hiện đầu tiên sql_batch_starting
, chúng ta có thể thấy tất cả các câu lệnh được bao gồm trong lô đó:
select * from humanresources.department where departmentid = 1;
select * from humanresources.department where departmentid = 2;
select * from humanresources.department where departmentid = 3;
select * from humanresources.department where departmentid = 4;
Với điều đó giải thích về những gì một lô là, bây giờ đến câu trả lời cho câu hỏi của bạn trong khi chấm dứt lô. Các quy tắc cho các lô được tìm thấy trên tài liệu tham khảo BOL này về các lô :
TẠO DEFAULT, TẠO CHỨC NĂNG, TẠO QUY TRÌNH, TẠO QUY TẮC, TẠO SCHema, TẠO TRIGGER và TẠO VIEW có thể được kết hợp với các câu lệnh khác trong một đợt. Câu lệnh CREATE phải bắt đầu lô. Tất cả các câu lệnh khác theo sau trong đợt đó sẽ được hiểu là một phần của định nghĩa của câu lệnh CREATE đầu tiên.
Một bảng không thể thay đổi và sau đó các cột mới được tham chiếu trong cùng một lô.
Nếu một câu lệnh EXECUTE là câu lệnh đầu tiên trong một đợt, thì từ khóa EXECUTE là không bắt buộc. Từ khóa EXECUTE là bắt buộc nếu câu lệnh EXECUTE không phải là câu lệnh đầu tiên trong lô.
Tương tự, một số lỗi thời gian chạy (lỗi biên dịch sẽ không cho phép thực thi một đợt bắt đầu) xảy ra trong một đợt có thể gây ra các hành vi khác nhau: hủy bỏ toàn bộ lô hoặc tiếp tục lô và chỉ hủy bỏ câu lệnh vi phạm (ở trên liên kết đưa ra hai ví dụ thực sự tốt: Chẳng hạn, lỗi tràn số học sẽ dừng việc thực thi lô, trong khi đó lỗi vi phạm ràng buộc sẽ chỉ ngăn câu lệnh hiện tại hoàn thành nhưng lô sẽ tiếp tục thực thi).
Tuy nhiên, giống như nhiều thứ trong nghề nghiệp của chúng tôi, sở thích cá nhân sẽ là một động lực rất lớn đằng sau cách bạn với tư cách là một cá nhân và người viết mã T-SQL chấm dứt các lô. Một số người chỉ xác định rõ ràng các lô khi họ thực sự phải (xem ở trên đối với các yêu cầu đó) và những người khác chấm dứt các lô theo chương trình 100% thời gian , ngay cả khi họ chỉ thực hiện một câu lệnh trong Cửa sổ truy vấn trong SSMS. Hầu hết mọi người thường rơi ở đâu đó ở giữa hai ranh giới đó. Đối với những gì nó có giá trị, các bộ kết thúc câu lệnh có cùng một điều với rất ít yêu cầu được thi hành. Một phần lớn của tất cả những điều này là kiểu mã , trong đó nó không được thi hành (trong SSMS và SQLCMD).