GO không phải là lệnh T-SQL. Là một dấu phân cách hàng loạt. Công cụ khách (SSM, sqlcmd, osql, v.v.) sử dụng nó để cắt một cách hiệu quả tệp tại mỗi lần GO và gửi đến máy chủ các lô riêng lẻ. Vì vậy, rõ ràng là bạn không thể sử dụng GO bên trong IF, cũng như bạn không thể mong đợi các biến mở rộng phạm vi theo lô.
Ngoài ra, bạn không thể bắt các ngoại lệ nếu không kiểm tra XACT_STATE()
để đảm bảo giao dịch không bị hủy.
Sử dụng GUID cho ID luôn ít nhất là đáng ngờ.
Sử dụng ràng buộc NOT NULL và cung cấp 'hướng dẫn' mặc định như '{00000000-0000-0000-0000-000000000000}'
cũng không thể đúng.
Đã cập nhật:
- Tách ALTER và UPDATE thành hai đợt.
- Sử dụng phần mở rộng sqlcmd để ngắt tập lệnh do lỗi. Điều này được hỗ trợ bởi SSMS khi bật chế độ sqlcmd , sqlcmd và cũng rất khó để hỗ trợ nó trong thư viện ứng dụng khách: dbutilsqlcmd .
- sử dụng
XACT_ABORT
để buộc lỗi làm gián đoạn hàng loạt. Điều này thường được sử dụng trong các kịch bản bảo trì (thay đổi lược đồ). Các thủ tục được lưu trữ và tập lệnh logic ứng dụng nói chung sử dụng khối TRY-CATCH thay thế, nhưng với sự cẩn thận thích hợp: Xử lý ngoại lệ và giao dịch lồng nhau .
tập lệnh ví dụ:
:on error exit
set xact_abort on;
go
begin transaction;
go
if columnproperty(object_id('Code'), 'ColorId', 'AllowsNull') is null
begin
alter table Code add ColorId uniqueidentifier null;
end
go
update Code
set ColorId = '...'
where ...
go
commit;
go
Chỉ một tập lệnh thành công mới đạt đến COMMIT
. Bất kỳ lỗi nào cũng sẽ hủy bỏ tập lệnh và khôi phục.
Tôi đã sử dụng COLUMNPROPERTY
để kiểm tra sự tồn tại của cột, bạn có thể sử dụng bất kỳ phương pháp nào bạn thích (ví dụ:lookup sys.columns
).