Bạn đã bỏ lỡ một số phần khác của cuốn sách. Đúng, Steven đúng - nếu một ngoại lệ xảy ra trong một khối, tất cả các hiệu ứng DML trước đó vẫn được giữ nguyên. Tuy nhiên, sẽ có đề cập khác trong cuốn sách rằng bất kỳ thực thi SQL hoặc PL / SQL cấp cao nhất nào (tức là cả khối ẩn danh) sẽ mở một con trỏ cho câu lệnh đó và nếu có ngoại lệ trong quá trình thực thi của con trỏ, tất cả các hiệu ứng DML sẽ được thực hiện trong quá trình thực thi của con trỏ được cuộn lại. Có lẽ một ví dụ đơn giản sẽ cho bạn manh mối ...
Trong ví dụ ban đầu của bạn, bạn đã thực hiện ...
BEGIN
DELETE FROM dml_exception;
raise value_error;
END;
... như câu lệnh cấp cao nhất. Có, ở cuối khối, mặc dù vẫn ở trong, delete
của bạn các hiệu ứng vẫn ở nguyên vị trí. Tuy nhiên, khối của bạn đã đưa ra một ngoại lệ được lan truyền đến tận con trỏ cấp cao nhất. Do đó, để tuân thủ các nguyên tắc của tính nguyên tử
, Oracle đã khôi phục tất cả các hiệu ứng đang chờ xử lý của con trỏ đã mở.
Nếu bạn gọi khối PL / SQL của mình từ bên trong một khối PL / SQL cấp cao nhất khác, khối này sẽ xử lý và không nâng lại ngoại lệ đã nêu trong khối PL / SQL cấp thấp hơn, ...
BEGIN
BEGIN
DELETE FROM dml_exception;
raise value_error;
END;
EXCEPTION
WHEN others THEN NULL;
END;
..., sau đó delete
của bạn các hiệu ứng sẽ vẫn ở nguyên vị trí. (Và vì không có cam kết nào trong khối đó, bạn sẽ có một giao dịch đang diễn ra.)