2009-11-19 25 views
14

Chúng tôi có thể sử dụng RAISE để kích hoạt ngoại lệ. Chúng tôi cần sử dụng những tình huống cụ thể nào để sử dụng RAISE_APPLICATION_ERROR?Oracle: tình huống sử dụng RAISE_APPLICATION_ERROR là gì?

Cảm ơn.

+0

Tôi đã tìm thấy một liên kết hữu ích cho câu hỏi tương tự. http://www.toadworld.com/platforms/oracle/b/weblog/archive/2010/07/14/raise-vs-raise-application-error.aspx –

Trả lời

27

Có hai cách sử dụng cho RAISE_APPLICATION_ERROR. Đầu tiên là thay thế các thông điệp ngoại lệ chung của Oracle bằng các thông báo của chúng ta, có ý nghĩa hơn. Thứ hai là tạo ra các điều kiện ngoại lệ của riêng chúng ta, khi Oracle không ném chúng.

Quy trình sau minh họa cả hai cách sử dụng. Nó thực thi một quy tắc kinh doanh mà nhân viên mới không thể được thuê trong tương lai. Nó cũng ghi đè hai ngoại lệ của Oracle. Một là DUP_VAL_ON_INDEX, được ném bởi một khóa duy nhất trên EMP(ENAME). Khác là một ngoại lệ do người dùng xác định được ném khi khóa ngoài giữa EMP(MGR)EMP(EMPNO) bị vi phạm (vì người quản lý phải là nhân viên hiện có).

create or replace procedure new_emp 
    (p_name in emp.ename%type 
     , p_sal in emp.sal%type 
     , p_job in emp.job%type 
     , p_dept in emp.deptno%type 
     , p_mgr in emp.mgr%type 
     , p_hired in emp.hiredate%type := sysdate) 
is 
    invalid_manager exception; 
    PRAGMA EXCEPTION_INIT(invalid_manager, -2291); 
    dummy varchar2(1); 
begin 
    -- check hiredate is valid 
    if trunc(p_hired) > trunc(sysdate) 
    then 
     raise_application_error 
      (-20000 
      , 'NEW_EMP::hiredate cannot be in the future'); 
    end if; 

    insert into emp 
     (ename 
      , sal 
      , job 
      , deptno 
      , mgr 
      , hiredate) 
    values  
     (p_name 
      , p_sal 
      , p_job 
      , p_dept 
      , p_mgr 
      , trunc(p_hired)); 
exception 
    when dup_val_on_index then 
     raise_application_error 
      (-20001 
      , 'NEW_EMP::employee called '||p_name||' already exists' 
      , true); 
    when invalid_manager then 
     raise_application_error 
      (-20002 
      , 'NEW_EMP::'||p_mgr ||' is not a valid manager'); 

end; 
/

Làm thế nào nó trông giống:

SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate+1) 
BEGIN new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate+1); END; 

* 
ERROR at line 1: 
ORA-20000: NEW_EMP::hiredate cannot be in the future 
ORA-06512: at "APC.NEW_EMP", line 16 
ORA-06512: at line 1 

SQL> 
SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 8888, sysdate) 
BEGIN new_emp ('DUGGAN', 2500, 'SALES', 10, 8888, sysdate); END; 

* 
ERROR at line 1: 
ORA-20002: NEW_EMP::8888 is not a valid manager 
ORA-06512: at "APC.NEW_EMP", line 42 
ORA-06512: at line 1 


SQL> 
SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate) 

PL/SQL procedure successfully completed. 

SQL> 
SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate) 
BEGIN new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate); END; 

* 
ERROR at line 1: 
ORA-20001: NEW_EMP::employee called DUGGAN already exists 
ORA-06512: at "APC.NEW_EMP", line 37 
ORA-00001: unique constraint (APC.EMP_UK) violated 
ORA-06512: at line 1 

Note đầu ra khác nhau từ hai cuộc gọi đến RAISE_APPLICATION_ERROR trong những ngoại lệ chặn. Đặt đối số thứ ba tùy chọn thành TRUE nghĩa là RAISE_APPLICATION_ERROR bao gồm ngoại lệ kích hoạt trong ngăn xếp, điều này có thể hữu ích cho việc chẩn đoán.

Có nhiều thông tin hữu ích hơn trong the PL/SQL User's Guide.

1

nếu ứng dụng của bạn chấp nhận lỗi tăng từ Oracle, thì bạn có thể sử dụng nó. chúng ta có một ứng dụng, mỗi khi một lỗi xảy ra, chúng ta gọi raise_application_error, ứng dụng sẽ bật lên một hộp màu đỏ để hiển thị thông báo lỗi chúng tôi cung cấp thông qua phương thức này.

Khi sử dụng mã dotnet, tôi chỉ sử dụng "nâng cao", cơ chế ngoại lệ dotnet sẽ tự động nắm bắt lỗi được chuyển bởi Oracle ODP và hiển thị bên trong mã ngoại lệ bắt của tôi.

3

Chỉ cần xây dựng thêm một chút về câu trả lời của Henry, bạn cũng có thể sử dụng các mã lỗi cụ thể, từ raise_application_error và xử lý chúng tương ứng ở phía máy khách. Ví dụ:

Giả sử bạn có một thủ tục PL/SQL như thế này để kiểm tra sự tồn tại của một kỷ lục vị trí:

PROCEDURE chk_location_exists 
    (
     p_location_id IN location.gie_location_id%TYPE 
    ) 
    AS 
     l_cnt INTEGER := 0; 
    BEGIN 
     SELECT COUNT(*) 
     INTO l_cnt 
     FROM location 
     WHERE gie_location_id = p_location_id; 

     IF l_cnt = 0 
     THEN 
      raise_application_error(
      gc_entity_not_found, 
      'The associated location record could not be found.'); 
     END IF; 
    END; 

Các raise_application_error cho phép bạn nâng cao một mã lỗi cụ thể. Trong tiêu đề gói, bạn có thể xác định: gc_entity_not_found INTEGER := -20001;

Nếu bạn cần mã lỗi khác cho các loại lỗi, bạn có thể xác định mã lỗi khác sử dụng -20.002, -20.003 vv

Sau đó trên máy khách bên, bạn có thể làm một cái gì đó như thế này (ví dụ này là dành cho C#):

/// <summary> 
/// <para>Represents Oracle error number when entity is not found in database.</para> 
/// </summary> 
private const int OraEntityNotFoundInDB = 20001; 

Và bạn có thể thực thi mã của bạn trong một try/catch

try 
{ 
    // call the chk_location_exists SP 
} 
catch (Exception e) 
{ 
    if ((e is OracleException) && (((OracleException)e).Number == OraEntityNotFoundInDB)) 
    { 
     // create an EntityNotFoundException with message indicating that entity was not found in 
     // database; use the message of the OracleException, which will indicate the table corresponding 
     // to the entity which wasn't found and also the exact line in the PL/SQL code where the application 
     // error was raised 
     return new EntityNotFoundException(
      "A required entity was not found in the database: " + e.Message); 
    } 
} 
7

Bạn sử dụng RAISE_APPLICATION_ERROR để tạo ra một ngoại lệ/lỗi kiểu Oracle dành riêng cho mã/nhu cầu của bạn. Sử dụng tốt các trợ giúp này để tạo mã rõ ràng hơn, dễ bảo trì hơn và dễ dàng hơn để gỡ lỗi.

Ví dụ, nếu tôi có một ứng dụng gọi một thủ tục lưu trữ có thêm một người sử dụng và người dùng đã tồn tại, bạn sẽ thường nhận lại một lỗi như:

ORA-00001: unique constraint (USERS.PK_USER_KEY) violated 

Rõ ràng lỗi này và thông điệp liên quan là không phải là duy nhất cho công việc bạn đang cố gắng làm. Việc tạo các lỗi ứng dụng Oracle của riêng bạn cho phép bạn rõ ràng hơn về mục đích của hành động và nguyên nhân của vấn đề.

raise_application_error(-20101, 'User ' || in_user || ' already exists!'); 

Bây giờ mã ứng dụng của bạn có thể viết trình xử lý ngoại lệ để xử lý tình trạng lỗi cụ thể này. Hãy nghĩ về nó như một cách để làm cho Oracle giao tiếp các điều kiện lỗi mà ứng dụng của bạn mong đợi trong một "ngôn ngữ" (vì thiếu một thuật ngữ tốt hơn) mà bạn đã xác định và có ý nghĩa hơn đối với miền vấn đề của ứng dụng của bạn.

Lưu ý rằng lỗi do người dùng xác định phải nằm trong khoảng từ -20000 đến -20999.

Sau đây link cung cấp nhiều thông tin tốt về chủ đề này và ngoại lệ của Oracle nói chung.

Các vấn đề liên quan