Câu hỏi hiển thị một tập lệnh lô nhiều câu lệnh. RAISE_APPLICATION_ERROR () chỉ thoát ra khỏi khối PL / SQL (chương trình con), không ra khỏi tập lệnh tổng thể (như Justin đã chỉ ra) vì vậy nó sẽ tiếp tục với các câu lệnh tiếp theo.
Đối với các tập lệnh hàng loạt, cách tốt nhất là sử dụng KHI BAO GIỜ EXIT SQLERROR. Đúng, nó là một chỉ thị SQL Plus, không phải là SQL tiêu chuẩn, nhưng khá di động; hầu hết các công cụ Oracle phổ biến hỗ trợ tập lệnh đều hỗ trợ chỉ thị này, ít nhất là một phần. Ví dụ sau hoạt động trong SQL Thêm vào đó, SQL * Developer, Toad, SQLsmith và có thể cả những người khác, và giải thích sự cố, nếu bạn nhận xét dòng này.
set serveroutput on
-- Without this line, things keep going
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK;
BEGIN
IF (1 > 0) THEN
DBMS_OUTPUT.PUT_LINE('First thing');
RAISE_APPLICATION_ERROR(-20000, 'Test failed'); -- not enough
END IF;
END;
/
-- This will execute if you remove WHEN SQLERROR.., so RAISE_APPLICATION_ERROR is not enough
BEGIN
DBMS_OUTPUT.PUT_LINE('Second thing - Executes anyway');
END;
/
Nếu bạn loại bỏ WHEN SQLERROR, tập lệnh sẽ tiếp tục và thực thi khối thứ 2, v.v., đó chính là điều mà câu hỏi yêu cầu phải tránh.
Trong trường hợp này, ưu điểm của các công cụ đồ họa mô phỏng sqlplus là chúng thực sự dừng tập lệnh và không gửi phần còn lại của tập lệnh vào trình bao lệnh dưới dạng các lệnh trình bao, đó là điều sẽ xảy ra nếu bạn dán tập lệnh vào SQL Cộng với việc chạy trong cửa sổ bảng điều khiển. SQL Plus có thể thoát ra do lỗi, nhưng các lệnh còn lại trong bộ đệm sau đó sẽ được xử lý bởi hệ điều hành shell, điều này hơi lộn xộn và tiềm ẩn nhiều rủi ro, nếu bạn có các lệnh shell trong các nhận xét (không phải là chưa từng thấy). Với SQLPlus, cách tốt nhất là luôn kết nối và sau đó thực thi tập lệnh hoặc chuyển nó vào đối số dòng lệnh