-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexchange_partition_by_list
173 lines (150 loc) · 4.07 KB
/
exchange_partition_by_list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
Important: Please consider this code as a benchmark. It perfectly works in my machine for my purposes. But maybe has to be updated for your needs. Thanks. Do not hesitate to contact me.
_ORALIB - oracle library;
_ora_table_name - partitioned oracle output table name
_ora_table_for_exch_name - table for partition exchange
_authdomain - authdomain
_orapath - orapath
_data_exch - table with data to be appended to table for partition exchange
_sqlldr_path - specify path to sqlldr client
_table - table for generating partition name and partition value
part_name - partition name
part_value - partitin value
Author: Wiktor Byrda
email: viktar.byrda@gmail.com
*/
/* Example of a table creation partitioned by list */
proc sql;
%if %sysfunc(exist( &_ORALIB..&_ora_table_name. )) %then %do;
DROP TABLE &_ORALIB..&_ora_table_name. ;
%end;
connect to oracle (authdomain=%str(%'&_AUTHDOMAIN.%') path=%str(%'&_ORApath.%'));
execute(
create table &_ora_table_name.
(POPULATION NUMBER,
COUNTRY VARCHAR2(30))
partition by list(COUNTRY)
( partition P_POLAND values ('POLAND')
)
)
by oracle;
disconnect from oracle;
quit;
/* create table for exchange - has to be exact copy of oracle table*/
%MACRO create_table_for_exchange(_oralib=, _ora_table_name=, _ora_table_for_exch_name=, _authdomain=, _orapath=);
proc sql;
%if %sysfunc(exist( &_ORALIB..&_ora_table_for_exch_name. )) %then %do;
DROP TABLE &_ORALIB..&_ora_table_for_exch_name. ;
%end;
connect to oracle (authdomain=%str(%'&_AUTHDOMAIN.%') path=%str(%'&_ORApath.%'));
execute(
create table &_ora_table_for_exch_name.
for exchange with table &_ora_table_name.
)
by oracle;
disconnect from oracle;
quit;
%MEND;
/* appending table for exchange partition */
%MACRO append_table_to_exchange(_oralib=, _data_exch=, _ora_table_for_exch_name= );
proc append base=&_ORALIB..&_ora_table_for_exch_name.
(
BULKLOAD=YES
BL_OPTIONS='PARALLEL=TRUE'
BL_SQLLDR_PATH='&_sqlldr_path.'
)
data=&_data_exch.;
run;
%mend;
/* ADD PARTITION IF NOT EXIST AND EXCHANGE*/
%MACRO exchange_part(_ora_table_name= ,_ora_table_for_exch_name= ,_AUTHDOMAIN = ,_ORApath = );
proc sql;
connect to oracle (authdomain=%str(%'&_AUTHDOMAIN.%') path=%str(%'&_ORApath.%'));
execute(
declare v_partition_count number;
table_name string(30);
begin
select %str(%'&_ora_table_name.%') into table_name from dual;
select count(*) into v_partition_count from user_tab_partitions
where table_name = %str(%'&_ora_table_name.%')
and partition_name = %str(%'&part_name.%');
if v_partition_count = 0 then
execute immediate 'alter table ' ||table_name|| ' ADD PARTITION '||' '||%str(%'&part_name.%')|| ' ' ||' values ('%str(%'&part_value.%')')';
end if;
end;
)
by oracle;
disconnect from oracle;
quit;
/* exchange partition */
proc sql;
connect to oracle (authdomain=%str(%'&_AUTHDOMAIN.%') path=%str(%'&_ORApath.%'));
execute (alter table &_ora_table_name.
exchange partition &part_name.
with table &_ora_table_for_exch_name.) by oracle;
disconnect from oracle;
quit;
%MEND;
/* TEST DATA */
/* creating table with data for partitions */
data TEST;
LENGTH COUNTRY $30;
input COUNTRY $ 1-9 POPULATION;
datalines;
GERMANY 83200000
GERMANY 83200000
GERMANY 83200000
GERMANY 83200000
GERMANY 83200000
FRANCE 68000000
SERBIA 6834000
SLOVAKIA 5447000
BELGIUM 11590000
SLOVENIA 2108000
;
RUN;
/* Macro for loading data into partitioned table */
%macro load_partitions;
PROC SQL NOPRINT;
SELECT DISTINCT COUNTRY INTO: VAR_LIST SEPARATED BY ' '
FROM TEST
ORDER BY COUNTRY;
%PUT &=VAR_LIST;
QUIT;
%do i=1 %to %sysfunc(countw(&VAR_LIST));
%let next_country = %scan(&VAR_LIST, &i);
DATA TEST2;
SET TEST;
IF COUNTRY = "&next_country.";
RUN;
data _null_;
set test2;
call symputx('part_name', cats("P","_", COUNTRY));
call symputx('part_value', COUNTRY);
run;
%PUT &=PART_NAME &=PART_VALUE;
%create_table_for_exchange
(
_oralib=
,_ora_table_name=
,_ora_table_for_exch_name=
,_authdomain=
,_orapath=
);
%append_table_to_exchange
(
_oralib=
,_ora_table_for_exch_name=
,_data_exch = test2
)
;
%exchange_part
(
_ora_table_name =
,_ora_table_for_exch_name =
,_AUTHDOMAIN =
,_ORApath =
);
%END;
%MEND;
%load_partitions;