2013-02-22 43 views
7

Tôi đã tạo một quy trình được lưu trữ chạy một số lệnh để sửa đổi dữ liệu. Tôi chỉ muốn giao dịch nếu mọi thứ thành công. Tôi đang làm điều này bằng cách sử dụng một khối try-catch theo cách dưới đây (trong đó khối catch của tôi trong những điều thực sự sử dụng RAISERROR trở về thông báo lỗi):SQL: Thử/Bắt không gặp lỗi khi cố gắng truy cập vào bảng mà không thể tìm thấy

BEGIN TRY 
    BEGIN TRANSACTION 
    UPDATE Table1 SET MyVarcharColumn = 'test' 
    UPDATE Table2 SET MyBitColumn = 1 
    UPDATE Table3 SET MyIntColumn = 42 
    COMMIT TRANSACTION 
END TRY 
CATCH 
    ROLLBACK TRANSACTION 
END CATCH 

đó làm việc theo cách tôi muốn nó. Ví dụ, nếu tôi đặt MyBitColumn thành 'b' thay vì 1, lỗi sẽ bị bắt, kiểm soát các luồng tới CATCH và giao dịch không được cam kết.

Một vấn đề mà tôi nhận thấy là nếu Table3 không tồn tại trong cơ sở dữ liệu thì nó bị lỗi (tên đối tượng không hợp lệ), nhưng khối CATCH không bao giờ được thực thi và giao dịch vẫn mở.

Tôi muốn xử lý việc này để xử lý mọi cơ sở dữ liệu được sửa đổi (hoặc điều gì đó xảy ra khi thủ tục được lưu trữ này được thêm đúng cách, nhưng một trong các bảng không phải là).

Tôi nên xử lý các trường hợp lỗi này như thế nào?

-Cảm ơn bạn đã được trợ giúp.

Trả lời

9

Vào đầu kịch bản của bạn sử dụng SET XACT_ABORT

SET XACT_ABORT ON 

Khi SET XACT_ABORT là ON, nếu một tuyên bố Transact-SQL đặt ra một thời gian chạy lỗi , toàn bộ giao dịch được chấm dứt và cuộn lại.

Tôi không nghĩ rằng sẽ có thể:

Các loại sau đây của các lỗi không được xử lý bởi một khối catch khi chúng xảy ra ở cùng một mức độ thực hiện như TRY ... CATCH xây dựng:

  • Lỗi biên dịch, chẳng hạn như lỗi cú pháp, ngăn chặn chạy hàng loạt.

  • Lỗi xảy ra trong quá trình biên dịch cấp tuyên bố, chẳng hạn như lỗi phân giải tên đối tượng xảy ra sau khi biên dịch vì độ phân giải tên hoãn lại .

Ref.

Ví dụ sau đây cho thấy làm thế nào một tên đối tượng giải quyết lỗi tạo ra bởi một câu lệnh SELECT không đánh bắt bởi các TRY ... CATCH xây dựng, nhưng ông ta bị khối catch khi cùng CHỌN statement được thực hiện bên trong một thủ tục lưu trữ.

USE AdventureWorks2012; 
GO 

BEGIN TRY 
    -- Table does not exist; object name resolution 
    -- error not caught. 
    SELECT * FROM NonexistentTable; 
END TRY 
BEGIN CATCH 
    SELECT 
     ERROR_NUMBER() AS ErrorNumber 
     ,ERROR_MESSAGE() AS ErrorMessage; 
END CATCH 

Lỗi không bị bắt và điều khiển đi ra khỏi TRY ... CATCH xây dựng để cấp trên trực tiếp.

+0

Cảm ơn bạn. Đó là hữu ích mà thiết lập đó gây ra các giao dịch để quay trở lại. Tuy nhiên, nó vẫn không thực hiện những gì trong khối CATCH sau khi lỗi. Điều này làm việc cho ứng dụng của tôi (kể từ khi lỗi được truyền lên trên anyways) nhưng nếu ai đó đang cố gắng để đảm bảo khối CATCH thực hiện vì các lý do khác, điều này sẽ không làm điều đó. – Luke

+0

À, hiểu rồi, họ không bị bắt vì những lỗi đó trong trường hợp đó. Cảm ơn! – Luke

-1
EXECUTE ('SELECT * FROM NonexistentTable'); 
Các vấn đề liên quan