[英]Adding exception handling and improving the below stored procedure and job in oracle
我已經在oracle數據庫中編寫了數據庫調度程序作業,該數據庫當前配置為每12小時運行一次。 該作業調用存儲過程,該存儲過程僅在mv刷新完成並且mv的上次刷新時間大於清理作業的上次運行時間時才執行增量表清理任務。
BEGIN
DBMS_SCHEDULER.create_job (
job_name => 'TABLE_CLEAN_UP_JOB',
job_type => 'STORED_PROCEDURE',
job_action => 'TABLE_CLEAN_UP',
start_date => SYSTIMESTAMP,
repeat_interval => 'freq=hourly;interval=12',
enabled => TRUE);
END;
/
下面是存儲過程
create or replace procedure TABLE_CLEAN_UP
is
refresh_date timestamp(6);
v_exists NUMBER;
outcome VARCHAR2(100);
cnt NUMBER;
i NUMBER := 0;
begin
SELECT count(1) into cnt FROM all_mviews WHERE owner = 'M_TO' AND mview_name = 'DC_CASHFLOW_VIEW' or mview_name = 'DC_CASHFLOW_VIEW_ZERO' and LAST_REFRESH_TYPE='COMPLETE';
if cnt=2 then
FOR rec IN (SELECT * FROM all_mviews WHERE owner = 'P_SM_TO' AND mview_name = 'DC_CASHFLOW_VIEW' or mview_name = 'DC_CASHFLOW_VIEW_ZERO' and LAST_REFRESH_TYPE='COMPLETE')
LOOP
Select LAST_START_DATE into refresh_date from USER_SCHEDULER_JOBS
where JOB_NAME='TABLE_CLEAN_UP_JOB';
if (CAST(rec.LAST_REFRESH_DATE AS TIMESTAMP) > refresh_date) then
i := i + 1;
end if;
END LOOP;
if i=2 then
delete DC_CASHFLOW_DELTA;
end if;
end if;
end;
/
現在對此有兩個擔憂
首先,我沒有進行適當的異常處理,因此請在上述存儲過程中建議如何進行適當的異常處理
還請告知如何將邏輯合並到循環中。如果未進行清理,則應休眠15分鍾,然后重新嘗試。
請告知人們如何進行改進,任何建議將不勝感激
民間可以有人建議嗎
這是一個清理后的版本(當然是未經試用的)。 我退出循環,因為它似乎可以歸結為兩個數字,並且我將您的where
子句中的or
構造更改為in ()
因為它更簡單,並且您缺少一些方括號,因此它會給出錯誤的結果。
我從不熱衷於對模式名稱進行硬編碼-也許應該將它們作為參數傳遞或從配置表中獲取?
異常處理看起來很好。 (如果沒有'TABLE_CLEAN_UP_JOB'
,它將失敗並顯示no_data_found
,但是我會說在這種情況下它應該失敗,因為缺少系統的一部分。也許特定情況下的異常處理程序可以使用raise_application_error
提供更好的消息,或只是記錄一條消息並繼續,如果那是您想要的,則由您決定。)
create or replace procedure table_clean_up
is
v_refresh_date date;
v_table_count_m integer;
v_table_count_p integer;
begin
select count(*) into v_table_count_m
from all_mviews
where owner = 'M_TO'
and mview_name in ('DC_CASHFLOW_VIEW','DC_CASHFLOW_VIEW_ZERO')
and last_refresh_type = 'COMPLETE';
if v_table_count_m = 2 then
select cast(last_start_date as date) into v_refresh_date
from user_scheduler_jobs
where job_name = 'TABLE_CLEAN_UP_JOB';
select count(*) into v_table_count_p
from all_mviews m
where m.owner = 'P_SM_TO'
and m.mview_name in ('DC_CASHFLOW_VIEW', 'DC_CASHFLOW_VIEW_ZERO')
and m.last_refresh_type = 'COMPLETE'
and m.last_refresh_date > v_refresh_date;
if v_table_count_p = 2 then
delete dc_cashflow_delta;
end if;
end if;
end;
我不太了解日程安排問題。 您有一個作業'TABLE_CLEAN_UP_JOB'
,每12小時調用一次上述過程,在該過程中,您檢查自上次運行作業(12小時前)以來是否進行了MV刷新,但是如果沒有,那么您想重新計划15分鍾后重試。 我可能會丟失一些東西,但是為什么不首先安排它每15分鍾運行一次呢?
無論如何,如果您真的想要一個過程調用坐在那里重試長達12個小時,則可以按照以下方式嘗試一些操作:
create or replace procedure table_clean_up
is
v_refresh_date date;
v_table_count_m integer;
v_table_count_p integer;
v_loopcount integer := 48;
begin
while v_loopcount > 0 loop
select count(*) into v_table_count_m
from all_mviews
where owner = 'M_TO'
and mview_name in ('DC_CASHFLOW_VIEW','DC_CASHFLOW_VIEW_ZERO')
and last_refresh_type = 'COMPLETE';
if v_table_count_m = 2 then
select cast(last_start_date as date) into v_refresh_date
from user_scheduler_jobs
where job_name = 'TABLE_CLEAN_UP_JOB';
select count(*) into v_table_count_p
from all_mviews m
where m.owner = 'P_SM_TO'
and m.mview_name in ('DC_CASHFLOW_VIEW', 'DC_CASHFLOW_VIEW_ZERO')
and m.last_refresh_type = 'COMPLETE'
and m.last_refresh_date > v_refresh_date;
if v_table_count_p = 2 then
delete dc_cashflow_delta;
exit;
end if;
end if;
dbms_lock.sleep(60 * 15);
v_loopcount := v_loopcount -1;
end loop;
end;
(有關休眠時間和嘗試迭代次數的幻數應該作為參數傳遞或在表中進行配置。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.