12/08/2018, 17:15 
               
            Xử lí lỗi trong Oracle
Giả sử ta có 1 table USERS(id, name, email). Insert into Users Values (1, 'NVA', 'a@gmail.com') (2, 'NVB', 'b@gmail.com') *Các lỗi ngoại lệ thường gặp: NO_DATA_FOUND: Kích hoạt khi một phát biếu SELECT INTO không thực hiện lời gọi hàm nhóm (SUM, COUNT, ...), không trả về ...
Giả sử ta có 1 table USERS(id, name, email).
 Insert into Users
 Values (1, 'NVA', 'a@gmail.com')
        (2, 'NVB', 'b@gmail.com')
*Các lỗi ngoại lệ thường gặp:
- NO_DATA_FOUND: Kích hoạt khi một phát biếu SELECT INTO không thực hiện lời gọi hàm nhóm (SUM, COUNT, ...), không trả về bất kì dòng nào.
 
DECLARE
    ename nvarchar(25);
BEGIN
    SELECT name
    INTO ename
    WHERE email = 'a';
END;
> Lúc này exception NO_DATA_FOUND được kích hoạt vì SELECT INTO
không trả về bất cứ giá trị nào => lỗi
- TO_MANY_ROW: kích hoạt khi mệnh đề SELECT INTO trả về hơn một dòng( vì mệnh đề SELECT INTO chỉ trả về 1 dòng).
 
DECLARE
    user users%ROWTYPE;
BEGIN
    SELECT *
    INTO ename;
END;
> Lúc này exception TO_MANY_ROW được kích hoạt vì SELECT INTO trả về 2 dòng dữ liệu => lỗi
- ZERO_DIVIDE: kích hoạt khi chương trình thực hiện phép chia cho 0.
 - LOGIN_DENIED: kích hoạt khi một người dùng thử kết nối vào Oracle bằng tên người dùng và mật khấu không hợp lệ.
 - PROGRAM_ERROR: một chương trình PL/SQL có lỗi bên trong.
 - VALUE_ERROR: kích hoạt khi một lỗi về chuyển đổi kiểu hoặc lỗi đồng nhất về mặt kích thước xảy ra.
 - DUP_VALUE_ON_INDEX: kích hoạt khi một chương trình đưa vào một giá trị trùng trong một cột hoặc các cột mà có chỉ mục duy nhất xây dựng nên các cột đó.
 - OTHERS: tất cả các lỗi ngoại lệ của Oracle được định nghĩa trước có thể được xử lí bằng cách sử dụng trình xử lí Others.
 
a. Sử dụng method "RAISE"
- Viết một procedure a/b:
 
CREATE OR REPLACE PROCEDURE sp_Test(a in number, b in number)
AS
    result  number(5, 2);
    my_exception EXCEPTION;
BEGIN
    IF b = 0 THEN
        RAISE my_exception;                // quăng ngoại lệ mẫu số = 0 vào biến my_exception
    ELSE
        result := a : b;
    END IF;
    EXCEPTION
        WHEN my_exception THEN                              // trường hợp này là ZERO_DIVIDE
            dbms_output.put_line('ZERO_DIVIDE');       // xuất lỗi ra màn hình
        WHEN OTHERS                                 // kết thúc xử lí lỗi = when others
            dbms_output.put_line('Generic exception');
END;
*Note:
- Phải chạy lệnh "SET SERVEROUTPUT ON" trong SQL, lúc đó lệnh dbms_output.put_line mới có hiệu lực in text.
 - Kiểu dữ liệu: number(5, 2) lấy tối đa 5 chữ số trước dấu phẩy, 2 chữ số sau dấu phẩy.
 - Kí hiệu := được sử dụng như toán tử gán.
 
b. Sử dụng thủ tục(procedure): RAISE_APPLICATION_ERROR:
- Syntax:
 
  raise_application_error(error_number, message [, {TRUE, FALSE}])
- Sử dụng: thường được sử ở hai vị trí khác nhau:
- Executable section.
 - Exception section.
 
 - Ví dụ:
 
DECLARE
    e_name exception;
BEGIN
    ...
    DELETE FROM employees
    WHERE last_name = 'NTD';
    IF SQL%NOTFOUND THEN
        RAISE e_name;                                  // executable section place
    END IF;
    
    EXCEPTION
    // exception section place
        When e_name THEN
            Raise_application_error(-20999, 'This is invalid lastname');
 END;