ORACLE定時任務呼叫儲存過程動態為表新增分割槽
1、建立需要自動分割槽的表
CREATE TABLE TEST(M DATA)
PARTITION BY RANGE(M)
(
PARTITION TEST_PAR_99991212 VALUES LESS THAN(TO_DATE('12-12-9999','DD-MM-YYYY'))
);
說明:建立的表必須要有一個足夠大的初始分割槽,因為後續增加分割槽是基於當前這個分割槽上面分裂而來的。
2、建立儲存過程
CREATE OR REPLACE PROCEDURE "BB"(TABLE_NAME IN VARCHAR2,BEFORE_DAY IN NUMBER,AFTER_DAY IN NUMBER) AS PAR_NAME VARCHAR2(50);--要建立的分割槽名稱 PAR_NAME2 VARCHAR2(400) V_DAY DATE;--分割槽對應日期 PAR_NAME_MAX VARCHAR2(20); PAR_EXISTS INTEGER; v_high_value VARCHAR2(255); v_partition_max_date date; CURSOR C_CUR(BEFOREDAY NUMBER,AFTERDAY NUMBER) IS SELECT (SYSDATE-BEFOREDAY)+ROWNUM-1 AS S_DATE FROM DUAL CONNECT BY ROWNUM <= TRUC((SYSDATE+AFTERDAY)-(SYSDATE-BEFOREDAY)); CURSOR C_CUR2(TABLENAME VARCHAR2) IS SELECT utp.table_name,utp.tablespace_name,utp.partition_name,utp.high_value,utp.high_value_length,utp.partition_position from user_tab_partitions utp where utp.table_name = TABLENAME AND utp.high_value_length <> 8 order by utp.partition_position ASC; BEGIN PAR_NAME_MAX := CONCAT(TABLE_NAME,'_PAR_MAX'); OPEN C_CUR(BEFORE_DAY,AFTER_DAY);--開啟遊標 loop FETCH C_CUR INTO V_DAY; EXIT WHERE C_CUR%NOTFOUND; --要建立的分割槽名稱 PAR_NAME := CONCAT(TABLE_NAME,CONCAT('_PAR_',TO_CHAR(V_DAY, 'YYYYMMDD'))); for utp in C_CUR2(TABLE_NAME) loop v_high_value := substr(utp.high_value,11,10); v_partition_max_date := to_date(v_high_value,'YYYY-MM-DD'); IF V_DAY + 1 < v_partition_max_date THEN PAR_NAME_MAX := TABLE_NAME || '_PAR_' || TO_CHAR(v_partition_max_date-1,'yyyymmdd'); EXIT; END IF; END loop; PAR_EXISTS := 0; SELECT COUNT(*) INTO PAR_EXISTS FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = TABLE_NAME AND PARTITION_NAME = PAR_NAME; IF PAR_EXISTS=0 THEN EXECUTE IMMEDIATE 'alter table '||TABLE_NAME||' split partition '||PAR_NAME_MAX||' AT (TO_DATE('''||TO_CHAR(V_DAY+1,'yyyymmdd')||''',''yyyymmdd'')) INTO (PARTITION '||PAR_NAME||',PARTITION '||PAR_NAME_MAX||') UPDATE GLOBAL INDEXES'; END IF; END loop; close C_CUR; COMMIT; END BB;
3、在oracle的命令介面執行下面操作,啟動一個job(正式專案裡最好使用spring的定時任務呼叫上面儲存過程)
SQL> variable job0712 number;
SQL> begin
2 dbms_job.submit(:job0712,'BB;',SYSDATE,'SYSDATE+1/1440');
3 end;
4 /
SAL> begin
2 dbms_job.run(:job0712);
3 end;
4 /
如下圖:
說明:
一些常用命令:
--給指定表新增分割槽
alter table TEST ADD PARTITION PART_AAA VALUES LESS THAN (TO_DATE('01-JUL-2009','DD-MON-YYYY'))
--分裂分割槽
altertable TEST2 split partition ORD_ACT_PART02 AT(TO_DATE('01-JUL-2009','DD-MON-YYYY')) INTO (PARTITION P1,PARTITIONORD_ACT_PART02);
--刪除指定表的指定分割槽
ALTERTABLE TEST3 DROP PARTITION part_aaa;
--檢視某張表所有分割槽資訊
SELECT *FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'TEST2'
--檢視指定分割槽記錄
SELECT *FROM TEST2 PARTITION (P1)
--檢視定時任務job相關資訊
SELECTjob,broken,what,interval,t.* from user_jobs t;
SELECTjob,broken,what,interval,t.next_sec ,SYSDATE from user_jobs t; --對應broken為N的時候job才為執行狀態
SELECT *from dba_jobs order by job;
--刪除job
A、查詢job對應的id
SELECTjob,broken,what,interval,t.next_sec ,SYSDATE from user_jobs t;
B、根據查詢到的job的id來刪除指定的job--在刪除分割槽表的時候,用下面的語句,否則分割槽表的資訊會放到oracle的垃圾站中去,會導致儲存過程中判斷分割槽是否存在的時候會有問題
DROPTABLE TEST2 PURGE
--下面的語句是清空oracle的垃圾站資料
PURGErecyclebin;