-
Notifications
You must be signed in to change notification settings - Fork 0
/
create.PyTL_Interfaces_Batches.sql
578 lines (558 loc) · 35.8 KB
/
create.PyTL_Interfaces_Batches.sql
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
/*
pythonist552 <at> gmail <dot> com
220828.1 = universal DDL script
*/
set linesize 2000
set serveroutput on
set verify off
declare
------------------------------------------------------------------------------------------------------------------------
-- Just only 2 parameters (V_TABLE_NAME, V_OLD_TABLE_NAMES) and 4 structures (V_TABLE_STRUCTURE, V_CONSTRAINTS, V_INDEXES, V_TRIGGERS) are required to be defined
------------------------------------------------------------------------------------------------------------------------
V_TABLE_NAME USER_TABLES.TABLE_NAME%type := 'PyTL_Interfaces_Batches';
-- if V_TABLE_NAME will be not found, but any table name from V_OLD_TABLE_NAMES will be found,
-- then the any one (couldn't predict which one) will be renamed into V_TABLE_NAME
V_OLD_TABLE_NAMES varchar2(4000 char) := ''; -- '' or 'POSSIBLE_OLD_NAME' or 'POSSIBLE_OLD_NAME1,POSSIBLE_OLD_NAME2,POSSIBLE_OLD_NAME3'
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
type T_FIELD_NAME is record ( -- desc ALL_TAB_COLUMNS;
COLUMN_NAME varchar2(256 char)
,DATA_TYPE varchar2(256 char)
,DATA_CHAR_LENGTH number
,CHAR_USED varchar2(1 char)
,DATA_DEFAULT varchar2(4000 char) -- it's LONG in the table ALL_TAB_COLUMNS
,OLD_COLUMN_NAMES varchar2(4000 char)
); type T_TABLE_FIELDS is table of T_FIELD_NAME;
V_TABLE_STRUCTURE T_TABLE_FIELDS := T_TABLE_FIELDS(
-- COLUMN_NAME DATA_TYPE DATA_CHAR_LENGTH CHAR_USED DATA_DEFAULT OLD_COLUMN_NAMES
T_FIELD_NAME('UNIQUE_ID' ,'NUMBER' ,22 ,'' ,'' ,'')
,T_FIELD_NAME('INTERFACE' ,'VARCHAR2' ,256 ,'C' ,'' ,'')
,T_FIELD_NAME('ORG' ,'VARCHAR2' ,50 ,'C' ,'' ,'')
,T_FIELD_NAME('INPUT_FILENAME' ,'VARCHAR2' ,256 ,'C' ,'' ,'')
,T_FIELD_NAME('INPUT_DATETIME' ,'TIMESTAMP(6)' ,'' ,'' ,'' ,'')
,T_FIELD_NAME('INPUT_BATCH_UID' ,'VARCHAR2' ,256 ,'C' ,'' ,'')
,T_FIELD_NAME('OUTPUT_BATCH_UID' ,'VARCHAR2' ,256 ,'C' ,'' ,'')
,T_FIELD_NAME('TOTALLY_RECORDS' ,'NUMBER' ,22 ,'' ,'0' ,'')
,T_FIELD_NAME('VALIDATED_SUCCESS','NUMBER' ,22 ,'' ,'0' ,'')
,T_FIELD_NAME('VALIDATED_FAILED' ,'NUMBER' ,22 ,'' ,'0' ,'')
,T_FIELD_NAME('PROCESSED_RECORDS','NUMBER' ,22 ,'' ,'0' ,'')
,T_FIELD_NAME('OUTPUT_FILENAME' ,'VARCHAR2' ,256 ,'C' ,'' ,'')
,T_FIELD_NAME('OUTPUT_DATETIME' ,'TIMESTAMP(6)' ,'' ,'' ,'' ,'')
,T_FIELD_NAME('LOCKED_BY' ,'VARCHAR2' ,256 ,'C' ,'' ,'')
,T_FIELD_NAME('STATUS_CODE' ,'NUMBER' ,22 ,'' ,'' ,'')
,T_FIELD_NAME('STATUS_DESC' ,'VARCHAR2' ,256 ,'C' ,'' ,'')
,T_FIELD_NAME('STATUS_MSG' ,'VARCHAR2' ,4000 ,'C' ,'' ,'')
);
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
type T_CONSTRAINT is record (
CONSTRAINT_NAME varchar2(256 char)
,CONSTRAINT_ACTION varchar2(256 char)
,CONSTRAINT_CONDTN varchar2(256 char)
,CONSTRAINT_REFCES varchar2(256 char)
); type T_CONSTRAINTS is table of T_CONSTRAINT;
V_CONSTRAINTS T_CONSTRAINTS := T_CONSTRAINTS(
-- alter table V_TABLE_NAME add constraint V_FOUND_OBJECT_NAME primary key (CONSTRAINT_CONDTN)
-- CONSTRAINT_NAME CONSTRAINT_ACTION CONSTRAINT_CONDTN CONSTRAINT_REFCES
T_CONSTRAINT('PK' ,'primary key' ,'UNIQUE_ID' ,'')
,T_CONSTRAINT('UNIQUE' ,'unique' ,'OUTPUT_BATCH_UID' ,'')
);
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
type T_INDEX is record (
INDEX_NAME varchar2(256 char)
,INDEX_UNIQUE varchar2(256 char)
,INDEX_FIELDS varchar2(256 char)
); type T_INDEXES is table of T_INDEX;
V_INDEXES T_INDEXES := T_INDEXES(
-- INDEX_NAME INDEX_UNIQUE INDEX_FIELDS
T_INDEX ('INTERFACE__ORG__OUTPUT_BATCH_UID' ,'' ,'INTERFACE, ORG, OUTPUT_BATCH_UID')
-- Not required: such index will be created automaticaly with primary key:
-- ,T_INDEX ('PK' ,'UNIQUE' ,'UNIQUE_ID')
);
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
-- Sequence+Trigger support:
-- {V_TABLE_NAME}_{COLUMN_NAME}_SEQ will be created if it doesn't exist
-- {V_TABLE_NAME}_{COLUMN_NAME}_TRG will be re-created to updated {COLUMN_NAME}
type T_TRIGGER is record (
COLUMN_NAME varchar2(256 char)
,TRIGGER_TYPE1 varchar2(256 char)
,TRIGGER_TYPE2 varchar2(256 char)
,TRIGGER_BODY varchar2(256 char)
); type T_TRIGGERES is table of T_TRIGGER;
V_TRIGGERES T_TRIGGERES := T_TRIGGERES(
-- COLUMN_NAME TRIGGER_TYPE1 TRIGGER_TYPE2 TRIGGER_BODY
-- T_TRIGGER ('UNIQUE_ID' ,'BEFORE INSERT ON' ,'FOR EACH ROW' ,'begin select '||V_TABLE_NAME||'__{COLUMN_NAME}__SEQ.nextval into :new.{COLUMN_NAME} from dual; end;')
);
------------------------------------------------------------------------------------------------------------------------
-- Go away. This is not a place to be. If you do try to enter here, you will fail and also be cursed.
-- If somehow you succeed, then do not complain that you entered unwarned, nor bother us with your deathbed prayers.
-- (c) Lord of Light by Roger Zelazny
------------------------------------------------------------------------------------------------------------------------
V_TMP_TABLE_NAME USER_TABLES.TABLE_NAME%type := 'TMP_STRUCTURE_TO_CREATE_UPDATE_TABLE';
V_MAX_COLUMN_NAME integer := -1;
V_SQL_TEXT varchar2(32000);
V_FLAG_OBJECT_EXISTS number;
V_FOUND_OBJECT_NAME varchar2(256);
begin
dbms_output.put_line('***************************************************************************');
dbms_output.put_line('******* Mission started.');
--------------------------------------------------------------------------------------------------------------------
-- Copy data from virtual table V_TABLE_STRUCTURE into real temporary table V_TMP_TABLE_NAME,
-- because of it's impossible to compare virtual table of records (structure) with real table
--------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------
-- Drop temporary table V_TMP_TABLE_NAME if it exists
----------------------------------------------------------------------------
select count(*) into V_FLAG_OBJECT_EXISTS from USER_TABLES where upper(TABLE_NAME) = upper(V_TMP_TABLE_NAME);
if V_FLAG_OBJECT_EXISTS = 1 then
------------------------------------------------------------------------
-- Drop already existed temporary table V_TMP_TABLE_NAME
------------------------------------------------------------------------
dbms_output.put_line('*** Found already existed temporary table ' || V_TMP_TABLE_NAME || ', so drop it...');
V_SQL_TEXT := 'drop table ' || V_TMP_TABLE_NAME;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Temporary table is droped successfully.');
end if;
------------------------------------------------------------------------
-- Create temporary table V_TMP_TABLE_NAME
------------------------------------------------------------------------
dbms_output.put_line('*** Create temporary table ' || V_TMP_TABLE_NAME || '...');
V_SQL_TEXT := 'create table ' || V_TMP_TABLE_NAME || ' (
COLUMN_NAME varchar2(256 char)
,DATA_TYPE varchar2(256 char)
,DATA_CHAR_LENGTH number
,CHAR_USED varchar2(1 char)
,DATA_DEFAULT varchar2(4000 char)
,OLD_COLUMN_NAMES varchar2(4000 char)
)';
-- dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Temporary table is created successfully.');
------------------------------------------------------------------------
-- Copy data from virtual table V_TABLE_STRUCTURE into real temporary table V_TMP_TABLE_NAME
------------------------------------------------------------------------
dbms_output.put_line('*** Copy data from virtual table V_TABLE_STRUCTURE into real temporary table ' || V_TMP_TABLE_NAME || '...');
for i in 1 .. V_TABLE_STRUCTURE.count loop
V_SQL_TEXT := 'insert into '|| V_TMP_TABLE_NAME ||'(COLUMN_NAME, DATA_TYPE, DATA_CHAR_LENGTH, CHAR_USED, DATA_DEFAULT, OLD_COLUMN_NAMES)'
|| ' values('
|| '''' || upper(V_TABLE_STRUCTURE(i).COLUMN_NAME) || ''''
|| ', '
|| '''' || upper(V_TABLE_STRUCTURE(i).DATA_TYPE) || ''''
|| ', '
|| case when V_TABLE_STRUCTURE(i).DATA_CHAR_LENGTH is null then 0 else V_TABLE_STRUCTURE(i).DATA_CHAR_LENGTH end
|| ', '
|| '''' || upper(V_TABLE_STRUCTURE(i).CHAR_USED) || ''''
|| ', '
|| '''' || replace(V_TABLE_STRUCTURE(i).DATA_DEFAULT, '''', '''''') || ''''
|| ', '
|| '''' || case when V_TABLE_STRUCTURE(i).OLD_COLUMN_NAMES is null then '' else V_TABLE_STRUCTURE(i).OLD_COLUMN_NAMES end || ''''
|| ')'
;
-- dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
-- dbms_output.put_line('*** Inserted successfully.');
end loop;
dbms_output.put_line('*** Copied successfully.');
--------------------------------------------------------------------------------------------------------------------
-- Rename from V_OLD_TABLE_NAMES into TABLE_NAME or create TABLE_NAME
--------------------------------------------------------------------------------------------------------------------
select count(*) into V_FLAG_OBJECT_EXISTS from USER_TABLES where upper(TABLE_NAME) = upper(V_TABLE_NAME);
if V_FLAG_OBJECT_EXISTS = 0 then
------------------------------------------------------------------------
-- Table V_TABLE_NAME doesn't exist
------------------------------------------------------------------------
dbms_output.put_line('*** Table ' || V_TABLE_NAME || ' is NOT found...');
if V_OLD_TABLE_NAMES is not null then
select count(*) into V_FLAG_OBJECT_EXISTS from USER_TABLES where
TABLE_NAME in (
select upper(trim(regexp_substr(V_OLD_TABLE_NAMES, '[^,]+', 1, level)))
from dual connect by regexp_substr(V_OLD_TABLE_NAMES, '[^,]+', 1, level) is not null
)
;
if V_FLAG_OBJECT_EXISTS = 1 then
------------------------------------------------------------------------
-- Rename if one of V_OLD_TABLE_NAMES is found
------------------------------------------------------------------------
select TABLE_NAME into V_FOUND_OBJECT_NAME from USER_TABLES where
TABLE_NAME in (
select upper(trim(regexp_substr(V_OLD_TABLE_NAMES, '[^,]+', 1, level)))
from dual connect by regexp_substr(V_OLD_TABLE_NAMES, '[^,]+', 1, level) is not null
)
and rownum = 1
;
dbms_output.put_line('*** Old table ' || V_FOUND_OBJECT_NAME || ' is FOUND, so rename it into new one...');
V_SQL_TEXT := 'rename ' || V_FOUND_OBJECT_NAME || ' to ' || V_TABLE_NAME;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Renamed successfully.');
else
dbms_output.put_line('*** No one table from [' || V_OLD_TABLE_NAMES || '] is NOT found...');
end if; -- Check if OLD table exists
end if; -- if V_OLD_TABLE_NAMES is not null then
------------------------------------------------------------------------
-- Check more one time, possible old table from V_OLD_TABLE_NAMES is found and renamed into V_TABLE_NAME
------------------------------------------------------------------------
select count(*) into V_FLAG_OBJECT_EXISTS from USER_TABLES where upper(TABLE_NAME) = upper(V_TABLE_NAME);
if V_FLAG_OBJECT_EXISTS = 0 then
dbms_output.put_line('*** Table ' || V_TABLE_NAME || ' is NOT found again, so create the new one...');
------------------------------------------------------------------------
-- Create table
------------------------------------------------------------------------
V_SQL_TEXT := 'create table ' || V_TABLE_NAME || '(' || chr(10);
-- get max length of field names
for i in 1 .. V_TABLE_STRUCTURE.count loop
V_MAX_COLUMN_NAME := greatest(V_MAX_COLUMN_NAME, length(V_TABLE_STRUCTURE(i).COLUMN_NAME));
end loop;
-- generate sql for execute immediate
for i in 1 .. V_TABLE_STRUCTURE.count loop
if i > 1 then
V_SQL_TEXT := V_SQL_TEXT || ',' || chr(10);
end if;
V_SQL_TEXT := V_SQL_TEXT || ' '
|| RPAD( V_TABLE_STRUCTURE(i).COLUMN_NAME, V_MAX_COLUMN_NAME+1, ' ')
|| V_TABLE_STRUCTURE(i).DATA_TYPE
|| case when V_TABLE_STRUCTURE(i).DATA_CHAR_LENGTH is not null then
'(' || V_TABLE_STRUCTURE(i).DATA_CHAR_LENGTH ||
case
when upper(V_TABLE_STRUCTURE(i).CHAR_USED) = 'B' then ' BYTE'
when upper(V_TABLE_STRUCTURE(i).CHAR_USED) = 'C' then ' CHAR'
else ''
end
|| ')'
else ''
end
|| case when V_TABLE_STRUCTURE(i).DATA_DEFAULT is not null then
' default ' || V_TABLE_STRUCTURE(i).DATA_DEFAULT
else ''
end
;
end loop;
V_SQL_TEXT := V_SQL_TEXT || chr(10) || ')';
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Created successfully.');
else
dbms_output.put_line('*** Old table ' || V_FOUND_OBJECT_NAME || ' is FOUND and successfully renamed into ' || V_TABLE_NAME || '...');
end if; -- Double check if table was not renamed from the old one
else
dbms_output.put_line('*** Table ' || V_TABLE_NAME || ' is FOUND...');
end if; -- Check if table not exists
-- *****************************************************************************************************************
-- https://community.oracle.com/tech/developers/discussion/3649885/execute-immediate-for-select-with-loop
-- Because of V_TMP_TABLE_NAME doesn't exist at the moment of script start, Oracle checks used tables
-- and prevent running of script with not existed table. Only code incapsulated into 'execute immediate' is possible to run.
-- *****************************************************************************************************************
--------------------------------------------------------------------------------------------------------------------
-- COLUMN_NAME exists in meta-structure (V_TMP_TABLE_NAME), but not exists in REAL (ALL_TAB_COLUMNS)
-- but one of OLD_COLUMN_NAMES exists in REAL (ALL_TAB_COLUMNS) => rename
--------------------------------------------------------------------------------------------------------------------
execute immediate q'{
declare
V_SQL_TEXT varchar2(32000);
begin
for COLUMNS_TO_RENAME in (
select t6.COLUMN_NAME as EXISTED_NAME, t5.NEW_NAME
from
(
select trim(regexp_substr(t4.OLD_COLUMN_NAMES, '[^,]+', 1, level)) as OLD_NAME, t4.COLUMN_NAME as NEW_NAME
from (
select t3.OLD_COLUMN_NAMES, t3.COLUMN_NAME from }' || V_TMP_TABLE_NAME || q'{ t3 where t3.COLUMN_NAME in (
select t1.COLUMN_NAME from }' || V_TMP_TABLE_NAME || q'{ t1
left outer join (select * from ALL_TAB_COLUMNS where upper(TABLE_NAME) = '}' || upper(V_TABLE_NAME) || q'{') t2 on t1.COLUMN_NAME = t2.COLUMN_NAME
where t2.DATA_TYPE is null
)
and t3.OLD_COLUMN_NAMES is not null
) t4
connect by regexp_substr(t4.OLD_COLUMN_NAMES, '[^,]+', 1, level) is not null
) t5
join (select * from ALL_TAB_COLUMNS where upper(TABLE_NAME) = '}' || upper(V_TABLE_NAME) || q'{') t6 on t6.COLUMN_NAME = t5.OLD_NAME
)
loop
dbms_output.put_line('[*] ' || COLUMNS_TO_RENAME.EXISTED_NAME || ' -> ' || COLUMNS_TO_RENAME.NEW_NAME);
V_SQL_TEXT := 'alter table }' || V_TABLE_NAME || q'{ rename column ' || COLUMNS_TO_RENAME.EXISTED_NAME || ' to ' || COLUMNS_TO_RENAME.NEW_NAME;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Column is renamed successfully.');
end loop;
end; }';
--------------------------------------------------------------------------------------------------------------------
-- COLUMN_NAME exists in meta-structure (V_TMP_TABLE_NAME), but not exist in REAL (ALL_TAB_COLUMNS) => add column
--------------------------------------------------------------------------------------------------------------------
execute immediate q'{
declare
V_SQL_TEXT varchar2(32000);
begin
for COLUMNS_TO_ADD in (
select t1.* from }' || V_TMP_TABLE_NAME || q'{ t1
left outer join (select * from ALL_TAB_COLUMNS where upper(TABLE_NAME) = '}' || upper(V_TABLE_NAME) || q'{') t2 on t1.COLUMN_NAME = t2.COLUMN_NAME
where t2.DATA_TYPE is null
)
loop
dbms_output.put_line('[+] ' || COLUMNS_TO_ADD.COLUMN_NAME);
V_SQL_TEXT := 'alter table }' || V_TABLE_NAME || q'{ add '
|| COLUMNS_TO_ADD.COLUMN_NAME
|| ' '
|| COLUMNS_TO_ADD.DATA_TYPE
|| case when COLUMNS_TO_ADD.DATA_CHAR_LENGTH is not null then
'(' || COLUMNS_TO_ADD.DATA_CHAR_LENGTH ||
case
when upper(COLUMNS_TO_ADD.CHAR_USED) = 'B' then ' BYTE'
when upper(COLUMNS_TO_ADD.CHAR_USED) = 'C' then ' CHAR'
else ''
end
|| ')'
else ''
end
|| case when COLUMNS_TO_ADD.DATA_DEFAULT is not null then
' default ' || COLUMNS_TO_ADD.DATA_DEFAULT
else ''
end
;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Column is added successfully.');
end loop;
end; }';
--------------------------------------------------------------------------------------------------------------------
-- COLUMN_NAME exists in REAL (ALL_TAB_COLUMNS), but not exist in meta-structure (V_TMP_TABLE_NAME) => drop column
--------------------------------------------------------------------------------------------------------------------
execute immediate q'{
declare
V_SQL_TEXT varchar2(32000);
begin
for COLUMNS_TO_DROP in (
select t2.COLUMN_NAME from }' || V_TMP_TABLE_NAME || q'{ t1
right outer join (select * from ALL_TAB_COLUMNS where upper(TABLE_NAME) = '}' || upper(V_TABLE_NAME) || q'{') t2 on t1.COLUMN_NAME = t2.COLUMN_NAME
where t1.DATA_TYPE is null
)
loop
dbms_output.put_line('[-] ' || COLUMNS_TO_DROP.COLUMN_NAME);
V_SQL_TEXT := 'alter table }' || V_TABLE_NAME || q'{ drop column ' || COLUMNS_TO_DROP.COLUMN_NAME;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Column is droped successfully.');
end loop;
end; }';
--------------------------------------------------------------------------------------------------------------------
-- COLUMN_NAME exists in both: in REAL (ALL_TAB_COLUMNS) and in meta-structure (V_TMP_TABLE_NAME)
-- but has DIFFERENT types, except DATA_DEFAULT (it's LONG in ALL_TAB_COLUMNS, so it's not possible to compare by ordinary way)
--------------------------------------------------------------------------------------------------------------------
execute immediate q'{
declare
V_SQL_TEXT varchar2(32000);
begin
for COLUMNS_TO_MODIFY in (
select
t1.*,
t2.DATA_TYPE as CURRENT_DATA_TYPE,
t2.DATA_LENGTH as CURRENT_DATA_LENGTH,
t2.CHAR_LENGTH as CURRENT_CHAR_LENGTH,
t2.CHAR_USED as CURRENT_CHAR_USED
from }' || V_TMP_TABLE_NAME || q'{ t1
left outer join (select * from ALL_TAB_COLUMNS where upper(TABLE_NAME) = '}' || upper(V_TABLE_NAME) || q'{') t2 on t1.COLUMN_NAME = t2.COLUMN_NAME
where
t2.COLUMN_NAME is not null
and (
t1.DATA_TYPE <> t2.DATA_TYPE
or t1.CHAR_USED <> t2.CHAR_USED
or ( t1.CHAR_USED is null and t1.DATA_CHAR_LENGTH <> 0 and t1.DATA_CHAR_LENGTH <> t2.DATA_LENGTH)
or ( t1.CHAR_USED is not null and t1.DATA_CHAR_LENGTH <> 0 and t1.DATA_CHAR_LENGTH <> t2.CHAR_LENGTH)
)
)
loop
dbms_output.put_line('[^] ' || COLUMNS_TO_MODIFY.COLUMN_NAME);
if COLUMNS_TO_MODIFY.CURRENT_DATA_TYPE <> COLUMNS_TO_MODIFY.DATA_TYPE then
dbms_output.put_line('[^] ' || ' DATA_TYPE from ''' || COLUMNS_TO_MODIFY.CURRENT_DATA_TYPE || ''' into ''' || COLUMNS_TO_MODIFY.DATA_TYPE || '''');
end if;
if COLUMNS_TO_MODIFY.CHAR_USED is null then
if COLUMNS_TO_MODIFY.CURRENT_DATA_LENGTH <> COLUMNS_TO_MODIFY.DATA_CHAR_LENGTH then
dbms_output.put_line('[^] ' || ' DATA_LENGTH from ''' || COLUMNS_TO_MODIFY.CURRENT_DATA_LENGTH || ''' into ''' || COLUMNS_TO_MODIFY.DATA_CHAR_LENGTH || '''');
end if;
else
if COLUMNS_TO_MODIFY.CURRENT_CHAR_LENGTH <> COLUMNS_TO_MODIFY.DATA_CHAR_LENGTH then
dbms_output.put_line('[^] ' || ' CHAR_LENGTH from ''' || COLUMNS_TO_MODIFY.CURRENT_CHAR_LENGTH || ''' into ''' || COLUMNS_TO_MODIFY.DATA_CHAR_LENGTH || '''');
end if;
end if;
if COLUMNS_TO_MODIFY.CURRENT_CHAR_USED <> COLUMNS_TO_MODIFY.CHAR_USED then
dbms_output.put_line('[^] ' || ' CHAR_USED from ''' || COLUMNS_TO_MODIFY.CURRENT_CHAR_USED || ''' into ''' || COLUMNS_TO_MODIFY.CHAR_USED || '''');
end if;
V_SQL_TEXT := 'alter table }' || V_TABLE_NAME || q'{ modify '
|| COLUMNS_TO_MODIFY.COLUMN_NAME
|| ' '
|| COLUMNS_TO_MODIFY.DATA_TYPE
|| case when COLUMNS_TO_MODIFY.DATA_CHAR_LENGTH is not null then
'(' || COLUMNS_TO_MODIFY.DATA_CHAR_LENGTH ||
case
when upper(COLUMNS_TO_MODIFY.CHAR_USED) = 'B' then ' BYTE'
when upper(COLUMNS_TO_MODIFY.CHAR_USED) = 'C' then ' CHAR'
else ''
end
|| ')'
else ''
end
|| case when COLUMNS_TO_MODIFY.DATA_DEFAULT is not null then
' default ' || COLUMNS_TO_MODIFY.DATA_DEFAULT
else ''
end
;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Column type is modified successfully.');
end loop;
end; }';
--------------------------------------------------------------------------------------------------------------------
-- COLUMN_NAME exists in both: in REAL (ALL_TAB_COLUMNS) and in meta-structure (V_TMP_TABLE_NAME)
-- but has DIFFERENT values in DATA_DEFAULT (it's LONG in ALL_TAB_COLUMNS, so it's not possible to compare by ordinary way)
--------------------------------------------------------------------------------------------------------------------
execute immediate q'{
declare
V_SQL_TEXT varchar2(32000);
v_DATA_DEFAULT_ASIS varchar2(4000 char);
begin
for LONG_COLUMNS_TO_MODIFY in (
select t1.*, t2.DATA_DEFAULT as ASIS from }' || V_TMP_TABLE_NAME || q'{ t1
right outer join (select * from ALL_TAB_COLUMNS where upper(TABLE_NAME) = '}' || upper(V_TABLE_NAME) || q'{' and DATA_DEFAULT is not null) t2 on t1.COLUMN_NAME = t2.COLUMN_NAME
)
loop
v_DATA_DEFAULT_ASIS := LONG_COLUMNS_TO_MODIFY.ASIS; -- because of impossible to compare LONG by other way
if v_DATA_DEFAULT_ASIS <> LONG_COLUMNS_TO_MODIFY.DATA_DEFAULT then
dbms_output.put_line('[^^] ' || LONG_COLUMNS_TO_MODIFY.COLUMN_NAME);
V_SQL_TEXT := 'alter table }' || V_TABLE_NAME || q'{ modify '
|| LONG_COLUMNS_TO_MODIFY.COLUMN_NAME
|| ' '
|| LONG_COLUMNS_TO_MODIFY.DATA_TYPE
|| case when LONG_COLUMNS_TO_MODIFY.DATA_CHAR_LENGTH is not null then
'(' || LONG_COLUMNS_TO_MODIFY.DATA_CHAR_LENGTH ||
case
when upper(LONG_COLUMNS_TO_MODIFY.CHAR_USED) = 'B' then ' BYTE'
when upper(LONG_COLUMNS_TO_MODIFY.CHAR_USED) = 'C' then ' CHAR'
else ''
end
|| ')'
else ''
end
|| case when LONG_COLUMNS_TO_MODIFY.DATA_DEFAULT is not null then
' default ' || LONG_COLUMNS_TO_MODIFY.DATA_DEFAULT
else ''
end
;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Column default data is modified successfully.');
end if;
end loop;
end; }';
--------------------------------------------------------------------------------------------------------------------
-- Add not existed sequences, re-create triggers
--------------------------------------------------------------------------------------------------------------------
dbms_output.put_line('*** Add not existed sequences, re-create triggers...');
for i in 1 .. V_TRIGGERES.count loop
V_FOUND_OBJECT_NAME := upper(V_TABLE_NAME || '__' || V_TRIGGERES(i).COLUMN_NAME || '__SEQ');
select count(*) into V_FLAG_OBJECT_EXISTS
from ALL_SEQUENCES t1
where
upper(t1.SEQUENCE_NAME) = V_FOUND_OBJECT_NAME
;
if V_FLAG_OBJECT_EXISTS <> 1 then
------------------------------------------------------------------------
-- Create new sequence V_FOUND_OBJECT_NAME if it doesn't exist
------------------------------------------------------------------------
dbms_output.put_line('*** Add sequence ' || V_FOUND_OBJECT_NAME || ' ...');
V_SQL_TEXT := 'create sequence ' || V_FOUND_OBJECT_NAME || ' increment by 1 start with 1 nomaxvalue nocycle cache 10';
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Sequence ' || V_FOUND_OBJECT_NAME || ' is created successfully.');
else
dbms_output.put_line('*** Existed sequence ' || V_FOUND_OBJECT_NAME || ' is FOUND. Nothing will be done.');
end if;
------------------------------------------------------------------------
-- Re-create trigger V_FOUND_OBJECT_NAME
------------------------------------------------------------------------
V_FOUND_OBJECT_NAME := upper(V_TABLE_NAME || '__' || V_TRIGGERES(i).COLUMN_NAME || '__TRG');
dbms_output.put_line('*** Re-create trigger ' || V_FOUND_OBJECT_NAME || ' ...');
V_SQL_TEXT := 'create or replace trigger ' || V_FOUND_OBJECT_NAME || ' ' || V_TRIGGERES(i).TRIGGER_TYPE1
|| ' ' || V_TABLE_NAME || ' ' || V_TRIGGERES(i).TRIGGER_TYPE2 || ' '
|| replace(V_TRIGGERES(i).TRIGGER_BODY, '{COLUMN_NAME}', V_TRIGGERES(i).COLUMN_NAME);
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Trigger ' || V_FOUND_OBJECT_NAME || ' is re-created successfully.');
end loop;
--------------------------------------------------------------------------------------------------------------------
-- Drop/add constraints
--------------------------------------------------------------------------------------------------------------------
dbms_output.put_line('*** Drop/add constraints...');
for i in 1 .. V_CONSTRAINTS.count loop
V_FOUND_OBJECT_NAME := upper(V_TABLE_NAME || '__' || V_CONSTRAINTS(i).CONSTRAINT_NAME);
select count(*) into V_FLAG_OBJECT_EXISTS
from ALL_CONSTRAINTS t1
where
upper(t1.TABLE_NAME) = upper(V_TABLE_NAME)
and upper(t1.CONSTRAINT_NAME) = V_FOUND_OBJECT_NAME
;
if V_FLAG_OBJECT_EXISTS = 1 then
------------------------------------------------------------------------
-- Drop already existed V_FOUND_OBJECT_NAME
------------------------------------------------------------------------
dbms_output.put_line('*** Found already existed constraint ' || V_FOUND_OBJECT_NAME || ', so drop it...');
V_SQL_TEXT := 'alter table ' || V_TABLE_NAME || ' drop constraint ' || V_FOUND_OBJECT_NAME || ' cascade';
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Constraint ' || V_FOUND_OBJECT_NAME || ' is droped successfully.');
end if;
dbms_output.put_line('*** Add constraint ' || V_FOUND_OBJECT_NAME || ' ...');
V_SQL_TEXT := 'alter table '|| upper(V_TABLE_NAME) || ' add constraint ' || V_FOUND_OBJECT_NAME
|| ' ' || V_CONSTRAINTS(i).CONSTRAINT_ACTION || ' (' || V_CONSTRAINTS(i).CONSTRAINT_CONDTN || ')'
;
if V_CONSTRAINTS(i).CONSTRAINT_REFCES is not null then
V_SQL_TEXT := V_SQL_TEXT || ' references ' || V_CONSTRAINTS(i).CONSTRAINT_REFCES;
end if;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Constraint ' || V_FOUND_OBJECT_NAME || ' is created successfully.');
end loop;
--------------------------------------------------------------------------------------------------------------------
-- Drop/add indexes
--------------------------------------------------------------------------------------------------------------------
dbms_output.put_line('*** Drop/add indexes...');
for i in 1 .. V_INDEXES.count loop
V_FOUND_OBJECT_NAME := upper(V_TABLE_NAME || '__' || V_INDEXES(i).INDEX_NAME);
select count(*) into V_FLAG_OBJECT_EXISTS
from ALL_INDEXES t1
where
upper(t1.TABLE_NAME) = upper(V_TABLE_NAME)
and upper(t1.INDEX_NAME) = V_FOUND_OBJECT_NAME
;
if V_FLAG_OBJECT_EXISTS = 1 then
------------------------------------------------------------------------
-- Drop already existed V_FOUND_OBJECT_NAME
------------------------------------------------------------------------
dbms_output.put_line('*** Found already existed index ' || V_FOUND_OBJECT_NAME || ', so drop it...');
V_SQL_TEXT := 'drop index ' || V_FOUND_OBJECT_NAME;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Index ' || V_FOUND_OBJECT_NAME || ' is droped successfully.');
end if;
dbms_output.put_line('*** Add index ' || V_FOUND_OBJECT_NAME || ' ...');
V_SQL_TEXT := 'create ' || V_INDEXES(i).INDEX_UNIQUE || ' index ' || V_FOUND_OBJECT_NAME
|| ' on '|| upper(V_TABLE_NAME) || ' (' || V_INDEXES(i).INDEX_FIELDS || ')';
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Index ' || V_FOUND_OBJECT_NAME || ' is created successfully.');
end loop;
--------------------------------------------------------------------------------------------------------------------
-- Drop temporary table V_TMP_TABLE_NAME
--------------------------------------------------------------------------------------------------------------------
dbms_output.put_line('*** Drop temporary table ' || V_TMP_TABLE_NAME || '...');
V_SQL_TEXT := 'drop table ' || V_TMP_TABLE_NAME;
dbms_output.put_line('* ' || V_SQL_TEXT);
execute immediate V_SQL_TEXT;
dbms_output.put_line('*** Temporary table is droped successfully.');
commit;
dbms_output.put_line('******* Mission acomplished.');
dbms_output.put_line('***************************************************************************');
end;
/
exit;