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.