2012-11-30 42 views
6

Tôi đang sử dụng SQL Server 2005. Tôi đã tạo một quy trình được lưu trữ hoạt động phần lớn thời gian, nhưng tôi đã tìm thấy một ví dụ về nơi nó không làm những gì tôi muốn.Cách lấy lỗi sql trong thủ tục lưu sẵn

Hiện nay, mã lệnh thực hiện một cái gì đó như thế này

if @@error <> 0 
    begin 
    select @message_error = "There was a database error adding product "+ @product + " to product line 
    end 

đâu @message_error là một biến đầu ra.

Vì vậy, tôi có thể select @@error và nhận được một số, nhưng tất cả những gì tôi thực sự muốn là lỗi SQL.

Giống như Xin chào, tôi không thể làm điều này vì có ràng buộc fk trên cột này hoặc bất kỳ thứ gì. Tôi tìm thấy bài viết này trên msdn http://msdn.microsoft.com/en-us/library/ms178592(v=sql.90).aspx

Nhưng nó không chỉ tạo ra ngoại lệ tùy chỉnh với RAISERROR, tôi không muốn tạo thông báo lỗi hoặc ngoại lệ của riêng mình, tôi chỉ muốn biết tại sao nội dung không hoạt động. Tôi có thể thực hiện các thủ tục lưu trữ thông qua Management Studio và xem lỗi SQL chính xác, nhưng điều này là tẻ nhạt cố gắng để phù hợp với dữ liệu từ trang web và chèn bằng tay theo cách đó.

Làm cách nào để nhận văn bản lỗi SQL vào biến đầu ra?

+2

Bạn đã xem ERROR_MESSAGE http://msdn.microsoft.com/en-us/library/ms190358.aspx chưa? – Romhein

Trả lời

11

Dưới đây là phần của một mẫu thủ tục được lưu trữ mà tôi sử dụng:

/* CREATE PROCEDURE... */ 

DECLARE 
    @ErrorMessage varchar(2000) 
,@ErrorSeverity tinyint 
,@ErrorState  tinyint 

/* Additional code */ 

BEGIN TRY 

/* Your code here */ 

END TRY 

BEGIN CATCH 
    SET @ErrorMessage = ERROR_MESSAGE() 
    SET @ErrorSeverity = ERROR_SEVERITY() 
    SET @ErrorState = ERROR_STATE() 
    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState) 

    BREAK 
END CATCH 

/* Further cleanup code */ 

Thử/Chặn khối có thể phức tạp nhưng triệt để hơn nhiều so với lỗi @@. Quan trọng hơn, bạn có thể sử dụng các hàm error_xxx() khác nhau bên trong chúng. Ở đây, tôi lưu trữ thông báo lỗi thích hợp trong biến @ErrorMessage, cùng với đủ dữ liệu khác để tăng lại lỗi. Từ đây, mọi tùy chọn đều có sẵn; bạn có thể biến @ErrorMessage thành một biến đầu ra, kiểm tra và xử lý các lỗi cụ thể hoặc xây dựng các thông báo lỗi của riêng bạn (hoặc điều chỉnh các thông báo lỗi hiện tại rõ ràng hơn - bạn có thể bị kích thích tìm ra tần suất bạn muốn làm điều đó). Các tùy chọn khác sẽ hiển thị themsleves.

Một số điều cần chú ý: trong một số trường hợp, SQL sẽ ném hai thông báo lỗi trở lại ... và error_message() sẽ chỉ bắt thông báo cuối cùng, thường có nội dung như "cố gắng tạo đối tượng không thành công", với lỗi thực sự được đưa ra trong thông báo lỗi đầu tiên. Đây là nơi xây dựng thông báo lỗi của riêng bạn.

+0

Đây là một câu trả lời thực sự tuyệt vời, và tôi không thể tin rằng tôi bỏ qua nó khi tôi ban đầu chấp nhận một câu trả lời. Cảm ơn! –

+0

Tôi gọi 'Error_Message()' trên một máy chủ khác nhưng nó nhận được NULL !!? Có bất kỳ cách nào để bắt lỗi trên máy chủ A bởi một Sp trên máy chủ B. trong mô hình này khi một lỗi được nêu ra trên máy chủ A, trong khối Catch của máy chủ A gọi một SP từ máy chủ B. nhưng không hoạt động! tại sao ? – Behzad

+0

@ Khosravifar, đó là một vấn đề đủ phức tạp mà bạn thực sự nên đăng nó như là câu hỏi riêng của mình - và thêm một liên kết đến nó ở đây như một bình luận. –

9

Bạn có thể sử dụng Thử/Bắt tổng quát và sau đó tạo thêm chi tiết về lỗi trong phần CATCH, ví dụ:

DECLARE @DetailedErrorDesc VARCHAR(MAX) 
BEGIN TRY 

--tsql code goes here 

END TRY 
BEGIN CATCH 

SELECT @DetailedErrorDesc =   
    CAST(ERROR_NUMBER() AS VARCHAR) + ' : '+ 
    CAST(ERROR_SEVERITY() AS VARCHAR) + ' : ' + 
    CAST(ERROR_STATE() AS VARCHAR) + ' : ' + 
    ERROR_PROCEDURE() + ' : ' + 
    ERROR_MESSAGE() + ' : ' + 
    CAST(ERROR_LINE() AS VARCHAR); 

--Now you can decide what to do with the detailed error message....return it or log it etc 

END CATCH 
+0

Tuyệt vời! Cảm ơn bạn!! –

3

sử dụng thử ... bắt và trong khối catch bạn có thể sử dụng ERROR_MESSAGE(), ERROR_LINE(), ERROR_PROCEDURE(), ERROR_STATE(), ERROR_SEVERITY(), ERROR_NUMBER() chức năng

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