Thực hiện xử lý lỗi T-SQL
Lỗi cho biết sự cố hoặc sự cố đáng chú ý phát sinh trong thao tác cơ sở dữ liệu. Công cụ Cơ sở dữ liệu SQL Server có thể tạo ra lỗi để đối phó với một sự kiện hoặc lỗi ở cấp hệ thống; hoặc bạn có thể tạo lỗi ứng dụng trong Transact-SQL của mình.
Các thành phần của lỗi công cụ cơ sở dữ liệu
Dù nguyên nhân là gì thì mọi lỗi đều bao gồm các yếu tố sau:
- Số lỗi - Số duy nhất xác định lỗi cụ thể.
- Thông báo lỗi - Văn bản mô tả lỗi.
- Mức độ nghiêm trọng - Chỉ báo số về mức độ nghiêm trọng từ 1 đến 25.
- State - Mã trạng thái nội bộ cho điều kiện công cụ cơ sở dữ liệu.
- Procedure - Tên của quy trình lưu trữ hoặc trình kích hoạt xảy ra lỗi.
- Số dòng - Câu lệnh nào trong lô hoặc thủ tục đã tạo ra lỗi.
Lỗi hệ thống
Lỗi hệ thống được xác định trước và bạn có thể xem chúng trong dạng xem hệ thống sys.messages . Khi xảy ra lỗi hệ thống, SQL Server có thể thực hiện hành động khắc phục tự động, tùy thuộc vào mức độ nghiêm trọng của lỗi. Ví dụ: khi xảy ra lỗi mức độ nghiêm trọng cao, SQL Server có thể đưa cơ sở dữ liệu ngoại tuyến hoặc thậm chí dừng dịch vụ công cụ cơ sở dữ liệu.
Lỗi tùy chỉnh
Bạn có thể tạo ra lỗi Transact-SQL để phản hồi các điều kiện cụ thể của ứng dụng hoặc để tùy chỉnh thông tin được gửi đến các ứng dụng máy khách để đáp ứng với lỗi hệ thống. Các lỗi ứng dụng này có thể được xác định tại chỗ nơi chúng được tạo hoặc bạn có thể xác định trước chúng trong bảng sys.messages cùng với các lỗi do hệ thống cung cấp. Số lỗi được sử dụng cho lỗi tùy chỉnh phải là 50001 trở lên.
Để thêm thông báo lỗi tùy chỉnh vào sys.messages, hãy sử sp_addmessage. Người dùng cho thư phải là thành viên của vai trò máy chủ cố định sysadmin hoặc serveradmin.
Đây là cú pháp sp_addmessage sau:
sp_addmessage [ @msgnum= ] msg_id , [ @severity= ] severity , [ @msgtext= ] 'msg'
[ , [ @lang= ] 'language' ]
[ , [ @with_log= ] { 'TRUE' | 'FALSE' } ]
[ , [ @replace= ] 'replace' ]
Dưới đây là ví dụ về thông báo lỗi tùy chỉnh bằng cú pháp này:
sp_addmessage 50001, 10, N’Unexpected value entered’;
Ngoài ra, bạn có thể xác định thông báo lỗi tùy chỉnh, các thành viên của vai trò máy chủ sysadmin cũng có thể sử dụng một tham số bổ sung, @with_log. Khi được đặt là TRUE, lỗi cũng sẽ được ghi lại trong nhật ký Ứng dụng Windows. Bất kỳ thông báo nào được ghi vào nhật ký Ứng dụng Windows cũng được ghi vào nhật ký lỗi SQL Server. Được tư pháp với việc @with_log sử dụng các tùy chọn bởi vì các quản trị viên mạng và hệ thống có xu hướng không thích các ứng dụng được "chatty" trong nhật ký hệ thống. Tuy nhiên, nếu lỗi cần phải bị mắc kẹt bởi một cảnh báo, lỗi trước tiên phải được ghi vào nhật ký Ứng dụng Windows.
Ghi
Không hỗ trợ nâng cao lỗi hệ thống.
Thư có thể được thay thế mà không cần xóa bỏ chúng trước tiên bằng cách sử dụng @replace tùy chọn = 'thay thế'.
Các thư có thể tùy chỉnh và các thư khác nhau có thể được thêm vào cho cùng một số lỗi cho nhiều ngôn ngữ, dựa trên một giá language_id khác nhau.
Ghi
Tin nhắn tiếng Anh language_id 1033.
Nâng lỗi bằng hàm RAISERROR
Cả PRINT và RAISERROR đều có thể được sử dụng để trả về thông tin hoặc thông báo cảnh báo cho ứng dụng. RAISERROR cho phép các ứng dụng nâng cao một lỗi mà sau đó có thể được đánh bắt bởi quá trình gọi điện thoại.
HÀM RAISERROR
Khả năng nâng cao lỗi trong T-SQL làm cho việc xử lý lỗi trong ứng dụng dễ dàng hơn, bởi vì nó được gửi như bất kỳ lỗi hệ thống nào khác. HÀM RAISERROR được dùng để:
- Trợ giúp khắc phục sự cố mã T-SQL.
- Kiểm tra giá trị của dữ liệu.
- Trả về thư có chứa văn bản biến số.
Ghi
Việc sử dụng câu lệnh PRINT tương tự như việc nâng cao lỗi có mức độ nghiêm trọng 10.
Đây là ví dụ về thông báo lỗi tùy chỉnh sử dụng RAISERROR.
RAISERROR (N'%s %d', -- Message text,
10, -- Severity,
1, -- State,
N'Custom error message number',
2)
Khi được kích hoạt, nó trả về:
Custom error message number 2
Trong ví dụ trước, %d là chỗ dành sẵn cho một số và%s là chỗ dành sẵn cho một chuỗi. Ngoài ra, bạn nên lưu ý rằng số thư không được đề cập. Khi lỗi với chuỗi thông báo được nêu ra bằng cú pháp này, chúng luôn có số lỗi 50000.
Nâng cao lỗi bằng cách sử dụng THROW
Câu lệnh THROW cung cấp một phương pháp đơn giản hơn trong việc nêu lỗi trong mã. Lỗi phải có số lỗi ít nhất là 50000.
NÉM
THROW khác với RAISERROR theo một số cách:
- Lỗi gây ra bởi THROW luôn có mức độ nghiêm trọng 16.
- Các thư trả về bởi THROW không liên quan đến bất kỳ mục nhập trong sys.sysmessages.
- Lỗi được đưa ra bởi THROW chỉ gây ra hủy bỏ giao dịch khi sử dụng kết hợp với SET XACT_ABORT BẬT và phiên kết thúc.
THROW 50001, 'An Error Occured',0
Ghi lại mã lỗi bằng cách sử @@Error
Hầu hết các mã xử lý lỗi truyền thống trong các ứng dụng SQL Server đều đã được tạo bằng @@ERROR. Xử lý ngoại lệ có cấu trúc được giới thiệu trong SQL Server 2005 và cung cấp một giải pháp thay thế mạnh mẽ cho việc sử @@ERROR. Nó sẽ được thảo luận trong bài học tiếp theo. Một lượng lớn mã xử lý lỗi SQL Server hiện có được dựa trên @@ERROR, vì vậy điều quan trọng là phải hiểu cách làm việc với mã.
@@ERROR
@@ERROR là một biến hệ thống chứa số lỗi của lỗi cuối cùng đã xảy ra. Một thách thức quan trọng với @@ERROR là giá trị mà nó nắm giữ sẽ nhanh chóng được đặt lại khi từng câu lệnh bổ sung được thực thi.
Ví dụ: hãy cân nhắc mã sau đây:
RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
PRINT 'Error=' + CAST(@@ERROR AS VARCHAR(8));
GO
Bạn có thể cho rằng, khi mã được thực thi, mã sẽ trả về số lỗi trong một chuỗi được in. Tuy nhiên, khi mã được thực thi, nó trả về:
Msg 50000, Level 16, State 1, Line 1
Message
Error=0
Lỗi đã được nêu ra nhưng thông báo được in ra là "Error=0". Trong dòng đầu tiên của kết quả, bạn có thể thấy rằng lỗi, như mong đợi, thực sự là 50000, với một thông báo được chuyển đến RAISERROR. Điều này là do câu lệnh IF tuân theo câu lệnh RAISERROR đã được thực thi thành công và khiến giá @@ERROR được đặt lại. Vì lý do này, khi làm việc với @@ERROR, điều quan trọng là ghi lại số lỗi vào một biến ngay khi biến số được nâng lên, sau đó tiếp tục xử lý với biến số.
Hãy xem mã sau đây minh họa điều này:
DECLARE @ErrorValue int;
RAISERROR(N'Message', 16, 1);
SET @ErrorValue = @@ERROR;
IF @ErrorValue <> 0
PRINT 'Error=' + CAST(@ErrorValue AS VARCHAR(8));
Khi mã này được thực thi, nó trả về đầu ra sau đây:
Msg 50000, Level 16, State 1, Line 2
Message
Error=50000
Bây giờ, số lỗi được báo cáo chính xác.
Tập trung xử lý lỗi
Một vấn đề quan trọng khác với việc sử dụng @@ERROR để xử lý lỗi là khó tập trung trong mã T-SQL của bạn. Xử lý lỗi có xu hướng kết thúc rải rác trong toàn bộ mã. Có thể tập trung xử lý lỗi bằng cách sử @@ERROR ở một mức độ nào đó, bằng cách sử dụng nhãn và câu lệnh GOTO. Tuy nhiên, điều này sẽ được cau có bởi hầu hết các nhà phát triển ngày nay như là một thực hành mã hóa nghèo.
Tạo cảnh báo lỗi
Đối với một số danh mục lỗi nhất định, người quản trị có thể tạo cảnh báo SQL Server, vì họ muốn được thông báo ngay khi những lỗi này xảy ra. Điều này thậm chí có thể áp dụng cho thông báo lỗi do người dùng xác định. Ví dụ: bạn có thể muốn đưa ra cảnh báo mỗi khi nhật ký giao dịch điền. Cảnh báo thường được sử dụng để đưa các lỗi có mức độ nghiêm trọng cao (chẳng hạn như mức độ nghiêm trọng 19 trở lên) đến sự chú ý của người quản trị.
Nâng cao cảnh báo
Cảnh báo có thể được tạo ra cho các thông báo lỗi cụ thể. Dịch vụ cảnh báo hoạt động bằng cách đăng ký chính nó như một dịch vụ gọi lại với dịch vụ ghi nhật ký sự kiện. Điều này có nghĩa là cảnh báo chỉ hoạt động với lỗi đã ghi nhật ký.
Có hai cách để làm cho một lỗi nâng cao một cảnh báo- bạn có thể sử dụng tùy chọn WITH LOG khi nâng cao lỗi hoặc thông báo có thể được thay đổi để làm cho nó đăng nhập bằng cách thực hiện sp_altermessage. Tùy chọn WITH LOG chỉ ảnh hưởng đến câu lệnh hiện tại. Sử dụng sp_altermessage thay đổi hành vi lỗi cho tất cả việc sử dụng trong tương lai. Sửa đổi lỗi hệ thống sp_altermessage chỉ có thể thực hiện từ SQL Server 2005 SP3 hoặc SQL Server 2008 SP1 trở đi.