1 CREATE OR REPLACE PROCEDURE p_dtl_bat_add_partition
2 (
3 i_table_name VARCHAR2,
4 i_month_id NUMBER
5 )
6 /*本程序主要对目标表创建一个以DATE_ID分区的月表:如musicdw.dwd_online_cdr_201210*/
7 AS
8 v_begin_date NUMBER; -- 月份的开始日期
9 v_end_date NUMBER; -- 月份的结束日期
10 l_sql VARCHAR2(8000);
11 v_table_name VARCHAR2(300); -- 结果月表的表名 -- 不带用户名
12 v_target_table_name VARCHAR2(300); -- 结果月表的表名 -- 带用户名
13 v_table_user VARCHAR2(200); -- 表所属的用户
14 v_tablespace VARCHAR2(200); -- 表所属的表空间
15
16 BEGIN
17
18 /*获取原表的用户,结果表保持跟原表一致*/
19 /*用户要具有访问dba_table的权限*/
20 BEGIN
21 SELECT t.owner,
22 t.tablespace_name
23 INTO v_table_user,
24 v_tablespace
25 FROM dba_tables t
26 WHERE t.table_name = upper(i_table_name);
27
28 v_tablespace := NVL(v_tablespace, 'TBS_DW_ORD');
29
30 EXCEPTION
31 /*表不存在的情况,默认是建在DW用户下*/
32 WHEN OTHERS THEN
33 v_table_user := 'MUSICDW';
34 v_tablespace := 'TBS_DW_ORD';
35 END;
36
37 /*获取标准的表名,如原表是 dwd_xxxx_dm ,新创建的表不要_DM了.*/
38 BEGIN
39 SELECT table_user || '.' || tatget_name || i_month_id,
40 tatget_name || i_month_id
41 INTO v_target_table_name,v_table_name /*获取标准的用户名.表名*/
42 FROM dic_backup_table_list
43 WHERE upper(table_name) = upper(i_table_name) AND
44 rownum <= 1;
45 END;
46
47 /*判断目标月表是否存在,存在的话则drop表*/
48 IF pkg_yyjd.func_exist_table(v_table_user, v_table_name)
49 THEN
50 EXECUTE IMMEDIATE 'drop table ' || v_target_table_name;
51 END IF;
52
53 /*初始化建表首先创建当月1号的分区*/
54 BEGIN
55 /*判断原表是否包含DATE_ID字段,有则按DATE_ID分区,无则不分区*/
56 l_sql := 'select * from ' || i_table_name || ' where date_id = 19900101 and 2 < 1';
57 EXECUTE IMMEDIATE l_sql;
58
59 v_begin_date := i_month_id || '01';
60 v_end_date := i_month_id || '02';
61
62 /*创建表和初始分区*/
63 l_sql := 'create table ' || v_target_table_name || ' partition by range(DATE_ID)
64 (partition P' || v_begin_date || ' values less THAN (' ||
65 v_end_date || ')
66 tablespace ' || v_tablespace || ' )
67 as select * from ' || i_table_name || ' where 1 =2';
68 EXECUTE IMMEDIATE l_sql;
69
70 /*再次初始化数据*/
71 v_begin_date := i_month_id || '02';
72 v_end_date := pkg_yyjd.func_get_last_day(i_month_id);
73
74 /*从当月二号开始增加分区*/
75 WHILE v_begin_date <= v_end_date
76 LOOP
77 l_sql := 'ALTER TABLE ' || v_target_table_name || ' ADD PARTITION P' || v_begin_date ||
78 ' values less than (' ||
79 to_char(TO_DATE(v_begin_date, 'yyyymmdd') + 1, 'YYYYMMDD') || ')';
80
81 EXECUTE IMMEDIATE l_sql;
82
83 /*while本来有这个功能,保险功能*/
84 IF v_begin_date = v_end_date
85 THEN
86 EXIT;
87 END IF;
88
89 /*循环增加1天*/
90 v_begin_date := to_number(to_char(TO_DATE(v_begin_date, 'yyyymmdd') + 1, 'YYYYMMDD'));
91
92 END LOOP;
93
94 EXCEPTION
95 WHEN OTHERS THEN
96 /*如果不存在DATE_ID字段的,则不建分区*/
97 l_sql := 'create table ' || v_target_table_name || ' as
98 select * from ' || i_table_name || ' where 1 = 2';
99 EXECUTE IMMEDIATE l_sql;
100 END;
101
102 END;
103 /