PL / SQL - Ngoại lệ
Trong chương này, chúng ta sẽ thảo luận về các Ngoại lệ trong PL / SQL. Một ngoại lệ là một điều kiện lỗi trong quá trình thực thi chương trình. PL / SQL hỗ trợ các lập trình viên nắm bắt các điều kiện như vậy bằng cách sử dụngEXCEPTIONtrong chương trình và một hành động thích hợp được thực hiện đối với tình trạng lỗi. Có hai loại ngoại lệ -
- Các ngoại lệ do hệ thống xác định
- Các ngoại lệ do người dùng xác định
Cú pháp xử lý ngoại lệ
Cú pháp chung để xử lý ngoại lệ như sau. Tại đây bạn có thể liệt kê nhiều trường hợp ngoại lệ nhất có thể. Ngoại lệ mặc định sẽ được xử lý bằng cách sử dụngWHEN others THEN -
DECLARE
<declarations section>
BEGIN
<executable command(s)>
EXCEPTION
<exception handling goes here >
WHEN exception1 THEN
exception1-handling-statements
WHEN exception2 THEN
exception2-handling-statements
WHEN exception3 THEN
exception3-handling-statements
........
WHEN others THEN
exception3-handling-statements
END;
Thí dụ
Hãy để chúng tôi viết một đoạn mã để minh họa khái niệm. Chúng tôi sẽ sử dụng bảng KHÁCH HÀNG mà chúng tôi đã tạo và sử dụng trong các chương trước -
DECLARE
c_id customers.id%type := 8;
c_name customerS.Name%type;
c_addr customers.address%type;
BEGIN
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
/
Khi đoạn mã trên được thực thi tại dấu nhắc SQL, nó tạo ra kết quả sau:
No such customer!
PL/SQL procedure successfully completed.
Chương trình trên hiển thị tên và địa chỉ của khách hàng có ID được cung cấp. Vì không có khách hàng nào có giá trị ID 8 trong cơ sở dữ liệu của chúng tôi, chương trình tăng ngoại lệ thời gian chạyNO_DATA_FOUND, được chụp trong EXCEPTION block.
Nâng cao ngoại lệ
Các ngoại lệ được máy chủ cơ sở dữ liệu tự động nâng lên bất cứ khi nào có bất kỳ lỗi cơ sở dữ liệu nội bộ nào, nhưng lập trình viên có thể nêu ra các ngoại lệ một cách rõ ràng bằng cách sử dụng lệnh RAISE. Sau đây là cú pháp đơn giản để tăng một ngoại lệ:
DECLARE
exception_name EXCEPTION;
BEGIN
IF condition THEN
RAISE exception_name;
END IF;
EXCEPTION
WHEN exception_name THEN
statement;
END;
Bạn có thể sử dụng cú pháp trên để nâng cao ngoại lệ tiêu chuẩn Oracle hoặc bất kỳ ngoại lệ nào do người dùng xác định. Trong phần tiếp theo, chúng tôi sẽ cung cấp cho bạn một ví dụ về việc nâng cao một ngoại lệ do người dùng xác định. Bạn có thể nâng cao các ngoại lệ tiêu chuẩn Oracle theo cách tương tự.
Ngoại lệ do người dùng xác định
PL / SQL cho phép bạn xác định các ngoại lệ của riêng bạn theo nhu cầu của chương trình của bạn. Một ngoại lệ do người dùng xác định phải được khai báo và sau đó được nêu ra một cách rõ ràng, sử dụng câu lệnh RAISE hoặc thủ tụcDBMS_STANDARD.RAISE_APPLICATION_ERROR.
Cú pháp để khai báo một ngoại lệ là:
DECLARE
my-exception EXCEPTION;
Thí dụ
Ví dụ sau minh họa khái niệm này. Chương trình này yêu cầu ID khách hàng, khi người dùng nhập ID không hợp lệ, ngoại lệinvalid_id được nuôi dưỡng.
DECLARE
c_id customers.id%type := &cc_id;
c_name customerS.Name%type;
c_addr customers.address%type;
-- user defined exception
ex_invalid_id EXCEPTION;
BEGIN
IF c_id <= 0 THEN
RAISE ex_invalid_id;
ELSE
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
END IF;
EXCEPTION
WHEN ex_invalid_id THEN
dbms_output.put_line('ID must be greater than zero!');
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
/
Khi đoạn mã trên được thực thi tại dấu nhắc SQL, nó tạo ra kết quả sau:
Enter value for cc_id: -6 (let's enter a value -6)
old 2: c_id customers.id%type := &cc_id;
new 2: c_id customers.id%type := -6;
ID must be greater than zero!
PL/SQL procedure successfully completed.
Các ngoại lệ được xác định trước
PL / SQL cung cấp nhiều ngoại lệ được xác định trước, được thực thi khi bất kỳ quy tắc cơ sở dữ liệu nào bị chương trình vi phạm. Ví dụ: ngoại lệ xác định trước NO_DATA_FOUND được đưa ra khi câu lệnh SELECT INTO trả về không có hàng nào. Bảng sau liệt kê một số trường hợp ngoại lệ quan trọng được xác định trước:
ngoại lệ | Lỗi Oracle | SQLCODE | Sự miêu tả |
---|---|---|---|
ACCESS_INTO_NULL | 06530 | -6530 | Nó được nâng lên khi một đối tượng null được tự động gán một giá trị. |
CASE_NOT_FOUND | 06592 | -6592 | Nó được đưa ra khi không có lựa chọn nào trong mệnh đề WHEN của câu lệnh CASE được chọn và không có mệnh đề ELSE. |
COLLECTION_IS_NULL | 06531 | -6531 | Nó được nâng lên khi một chương trình cố gắng áp dụng các phương thức thu thập khác với EXISTS cho một bảng hoặc varray lồng nhau chưa được khởi tạo hoặc chương trình cố gắng gán giá trị cho các phần tử của một bảng hoặc varray lồng nhau chưa được khởi tạo. |
DUP_VAL_ON_INDEX | 00001 | -1 | Nó được nâng lên khi các giá trị trùng lặp được cố gắng lưu trữ trong một cột có chỉ mục duy nhất. |
INVALID_CURSOR | 01001 | -1001 | Nó được nâng lên khi cố gắng thực hiện một thao tác con trỏ không được phép, chẳng hạn như đóng một con trỏ chưa mở. |
INVALID_NUMBER | 01722 | -1722 | Nó được nâng lên khi chuyển đổi một chuỗi ký tự thành một số không thành công vì chuỗi không đại diện cho một số hợp lệ. |
ĐĂNG NHẬP BỊ TỪ CHỐI | 01017 | -1017 | Nó được nâng lên khi một chương trình cố gắng đăng nhập vào cơ sở dữ liệu bằng tên người dùng hoặc mật khẩu không hợp lệ. |
KHÔNG TÌM THẤY DỮ LIỆU NÀO | 01403 | +100 | Nó được nâng lên khi câu lệnh SELECT INTO trả về không có hàng nào. |
NOT_LOGGED_ON | 01012 | -1012 | Nó được đưa ra khi một lệnh gọi cơ sở dữ liệu được đưa ra mà không được kết nối với cơ sở dữ liệu. |
PROGRAM_ERROR | 06501 | -6501 | Nó được nêu ra khi PL / SQL có vấn đề nội bộ. |
ROWTYPE_MISMATCH | 06504 | -6504 | Nó được nâng lên khi con trỏ tìm nạp giá trị trong một biến có kiểu dữ liệu không tương thích. |
SELF_IS_NULL | 30625 | -30625 | Nó được nâng lên khi một phương thức thành viên được gọi, nhưng thể hiện của kiểu đối tượng không được khởi tạo. |
STORAGE_ERROR | 06500 | -6500 | Nó được nâng lên khi PL / SQL hết bộ nhớ hoặc bộ nhớ bị hỏng. |
TOO_MANY_ROWS | 01422 | -1422 | Nó được nâng lên khi một câu lệnh SELECT INTO trả về nhiều hơn một hàng. |
VALUE_ERROR | 06502 | -6502 | Nó được nâng lên khi xảy ra lỗi số học, chuyển đổi, cắt bớt hoặc sizeconstraint. |
ZERO_DIVIDE | 01476 | 1476 | Nó được nâng lên khi cố gắng chia một số cho không. |