2013-11-24 21 views
12

Tôi có một tập lệnh sql mà tôi phải chạy sau khi tôi nhập một kết xuất. trong số những thứ khác kịch bản thực hiện, nó như sau:DBMS_SCHEDULER.DROP_JOB chỉ khi tồn tại

BEGIN 
--remove program   
SYS.DBMS_SCHEDULER.DROP_PROGRAM(program_name=>'STATISTICS_COLUMNS_PROG',FORCE=>TRUE); 
--remove job 
SYS.DBMS_SCHEDULER.DROP_JOB (job_name => 'STATISTICS_COLUMNS_JOB'); 
END; 

Somtimes công việc đã được giảm trong lược đồ ban đầu, các bãi chứa đến mà không có công việc và kịch bản thất bại:

ERROR at line 1: 
ORA-27475: "DMP_6633.STATISTICS_SET_COLUMNS_JOB" must be a job 
ORA-06512: at "SYS.DBMS_ISCHED", line 213 
ORA-06512: at "SYS.DBMS_SCHEDULER", line 657 
ORA-06512: at line 5 

thế nào có thể Tôi tránh thất bại này trong trường hợp công việc không tồn tại nhưng vẫn có thể thả nó nếu nó?

Trả lời

28

Có hai mẫu chính bạn có thể áp dụng để xử lý ngoại lệ; "nhìn trước khi bạn nhảy" (LBYL) và "dễ dàng hơn để yêu cầu sự tha thứ hơn sự cho phép" (EAFP). LBYL sẽ chủ trương kiểm tra xem liệu công việc có tồn tại hay không trước khi cố gắng xóa nó. EAFP sẽ liên quan đến việc cố gắng bỏ công việc và sau đó bắt giữ và bỏ qua lỗi cụ thể đó, nếu nó xảy ra.

Nếu bạn áp dụng LBYL, bạn có thể truy vấn chế độ xem hệ thống USER_SCHEDULER_JOBS để xem công việc của bạn có tồn tại không. Nếu có, hãy thả nó.

declare 
    l_job_exists number; 
begin 
    select count(*) into l_job_exists 
    from user_scheduler_jobs 
    where job_name = 'STATISTICS_COLUMNS_JOB' 
      ; 

    if l_job_exists = 1 then 
     dbms_scheduler.drop_job(job_name => 'STATISTICS_COLUMNS_JOB'); 
    end if; 
end; 

Đối với EAFP hơi khác; define your own exception bởi naming an internally defined exception và khởi tạo nó bằng mã lỗi bạn đang tìm kiếm. Nếu lỗi đó sau đó được nâng lên, không làm gì cả.

declare 
    job_doesnt_exist EXCEPTION; 
    PRAGMA EXCEPTION_INIT(job_doesnt_exist, -27475); 
begin 
    dbms_scheduler.drop_job(job_name => 'STATISTICS_COLUMNS_JOB'); 
exception when job_doesnt_exist then 
    null; 
end; 

Cần lưu ý hai điều về phương pháp thứ hai này.

  1. Tôi đang chỉ bắt lỗi do ngoại lệ cụ thể này gây ra. Nó sẽ có thể đạt được điều tương tự bằng cách sử dụng EXCEPTION WHEN OTHERS nhưng tôi rất muốn giới thiệu chống lại làm điều này.

    Nếu bạn xử lý ngoại lệ, bạn nên biết chính xác mình sẽ làm gì với nó. Nó không chắc rằng bạn có khả năng xử lý mọi ngoại lệ Oracle đúng cách sử dụng OTHERS và nếu bạn làm như vậy bạn có lẽ nên đăng nhập chúng ở đâu đó, nơi chúng sẽ được chú ý. Để báo giá từ số Guidelines for Avoiding and Handling Exceptions của Oracle:

    Bất cứ khi nào có thể, hãy viết trình xử lý ngoại lệ cho các ngoại lệ được đặt tên thay vì sử dụng các trình xử lý ngoại lệ KHÁC.

  2. Oracle's exception propagation hoạt động từ khối nội bộ sang khối ngoài nên nguyên nhân ban đầu cho lỗi sẽ là ngoại lệ đầu tiên.

+1

Tôi ước tôi có thể bỏ phiếu cho câu trả lời này hai lần! –

+0

Cảm ơn! Đó là một chủ nhật, thêm thời gian ... và tôi đã viết một số điều này trước khi @Ian. – Ben

+1

Đó là một ví dụ thực sự tốt về cách một câu trả lời chuyên nghiệp trông giống như! Cảm ơn phản ứng tuyệt vời! – SaschaM78

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