Compare commits
132 Commits
6039d6bce4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a35e28042b | ||
|
|
92feb95ae0 | ||
|
|
74b8857096 | ||
|
|
24997b1583 | ||
|
|
eb9b2bc38b | ||
|
|
2ea708a694 | ||
|
|
12c58f32a3 | ||
|
|
811df6e8b1 | ||
|
|
c2e9409e55 | ||
|
|
c96bf2051f | ||
|
|
5d0e03d7ad | ||
|
|
ffd6c7eeae | ||
|
|
bbdf008125 | ||
|
|
396e7416f6 | ||
|
|
0ed75875ac | ||
|
|
a7db9b67bc | ||
|
|
ce9b6eeff6 | ||
|
|
0725119b45 | ||
|
|
896e67bcb9 | ||
|
|
ad5a6f393a | ||
|
|
a4ac132b76 | ||
|
|
6468d12349 | ||
|
|
fe0f7bce18 | ||
|
|
6b2f60f413 | ||
|
|
ca11debd93 | ||
|
|
24e6bce18c | ||
|
|
aa03dd1616 | ||
|
|
9190681051 | ||
|
|
096994d514 | ||
|
|
1385bfb9e7 | ||
|
|
7d2fb34ad9 | ||
|
|
202b535f9f | ||
|
|
5ba6c30fda | ||
|
|
64a4b9a2f0 | ||
|
|
dec3e7137e | ||
|
|
0ecc119ee9 | ||
|
|
182e6240d3 | ||
|
|
b81e524351 | ||
|
|
73e99b6e76 | ||
|
|
113ea0a618 | ||
|
|
59e18d9b35 | ||
|
|
a58a5ae82a | ||
|
|
b537719b64 | ||
|
|
4de14b64fb | ||
|
|
36a04dde04 | ||
|
|
cad6e63479 | ||
|
|
7db10725a0 | ||
|
|
a13a9d415f | ||
|
|
1c6f552df9 | ||
|
|
e9d4056451 | ||
|
|
60b218d211 | ||
|
|
819b6f7880 | ||
|
|
c68d5bfe2c | ||
|
|
c607bbe26e | ||
|
|
1569237306 | ||
|
|
472a724fe0 | ||
|
|
04d4f6ac02 | ||
|
|
ca5d8b320c | ||
|
|
2605896469 | ||
|
|
b588b0bb72 | ||
|
|
6060f93fde | ||
|
|
99aca3af40 | ||
|
|
1089184367 | ||
|
|
e538706896 | ||
|
|
ff034fcd68 | ||
|
|
b85172ae84 | ||
|
|
577c94f363 | ||
|
|
11723f6c88 | ||
|
|
b63be15f5d | ||
|
|
28972e7428 | ||
|
|
866b886c70 | ||
|
|
3848a9471b | ||
|
|
cafa30f8f3 | ||
|
|
a0f4146a24 | ||
|
|
2b116c0256 | ||
|
|
204616252a | ||
|
|
93d2e537a9 | ||
|
|
2143a81aa0 | ||
|
|
b6cf54f103 | ||
|
|
6ade77c3c0 | ||
|
|
8ce07c3360 | ||
|
|
64dc830a2b | ||
|
|
020dacb571 | ||
|
|
057a4e7ce3 | ||
|
|
a9a51f19be | ||
|
|
fc6304c60b | ||
|
|
912b7a6466 | ||
|
|
b6f6446232 | ||
|
|
aa2f2f13f9 | ||
|
|
5c77d42d9a | ||
|
|
d370b9c9ef | ||
|
|
c5d39fc01d | ||
|
|
80916ea302 | ||
|
|
a4ab56e96d | ||
|
|
92c5261215 | ||
|
|
b34c942a8f | ||
|
|
d175179ddc | ||
|
|
d8a5edc3b1 | ||
|
|
d6c34085f7 | ||
|
|
2c40f091e0 | ||
|
|
255044f23b | ||
|
|
0053ecc556 | ||
|
|
3b7ce7de97 | ||
|
|
a3ec31341b | ||
|
|
1327410880 | ||
|
|
f4e9fb9cb2 | ||
|
|
26aba08759 | ||
|
|
b96becd8ef | ||
|
|
b1bb24e487 | ||
|
|
86535048fc | ||
|
|
9ffad718fe | ||
|
|
d443c4f07d | ||
|
|
cdd9dff32d | ||
|
|
70909ba8c4 | ||
|
|
88325f0b8c | ||
|
|
dc8031262c | ||
|
|
fc95b12c9e | ||
|
|
23b9962128 | ||
|
|
802c102f29 | ||
|
|
fa1f179be9 | ||
|
|
5e9233649e | ||
|
|
974f6eca25 | ||
|
|
c4f5ba48bc | ||
|
|
e6ab189dc9 | ||
|
|
e93140e962 | ||
|
|
f42777f480 | ||
|
|
19925603fa | ||
|
|
569c647b6c | ||
|
|
8a162ce9bf | ||
|
|
c508e1e4e2 | ||
|
|
d6fd0b3dbd | ||
|
|
32c7a5dcee |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -19,6 +19,8 @@ issues/
|
|||||||
ehthumbs.db
|
ehthumbs.db
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
|
MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/*
|
||||||
|
|
||||||
MARS_Packages/REL01/MARS-1056/confluence/
|
MARS_Packages/REL01/MARS-1056/confluence/
|
||||||
MARS_Packages/REL01/MARS-1056/log/
|
MARS_Packages/REL01/MARS-1056/log/
|
||||||
MARS_Packages/REL01/MARS-1046/confluence/
|
MARS_Packages/REL01/MARS-1046/confluence/
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_ADHOC_ADJUSTMENTS_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_ADHOC_ADJUSTMENTS_HEADER',
|
||||||
pParallelDegree => 1
|
pParallelDegree => 1,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_ADHOC_ADJUSTMENTS_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ADHOC_ADJ_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ADHOC_ADJ_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -44,7 +46,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_ADHOC_ADJUSTMENTS_ITEM',
|
pFolderName => 'ARCHIVE/LM/LM_ADHOC_ADJUSTMENTS_ITEM',
|
||||||
pParallelDegree => 1
|
pParallelDegree => 1,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_ADHOC_ADJUSTMENTS_ITEM',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ADHOC_ADJ_ITEM exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ADHOC_ADJ_ITEM exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -64,7 +68,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_ADHOC_ADJUSTMENTS_ITEM_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_ADHOC_ADJUSTMENTS_ITEM_HEADER',
|
||||||
pParallelDegree => 1
|
pParallelDegree => 1,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_ADHOC_ADJUSTMENTS_ITEM_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ADHOC_ADJ_ITEM_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ADHOC_ADJ_ITEM_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_BALANCESHEET_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_BALANCESHEET_HEADER',
|
||||||
pParallelDegree => 4
|
pParallelDegree => 4,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_BALANCESHEET_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_BALANCESHEET_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_BALANCESHEET_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -49,7 +51,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_BALANCESHEET_ITEM',
|
pFolderName => 'ARCHIVE/LM/LM_BALANCESHEET_ITEM',
|
||||||
pParallelDegree => 16
|
pParallelDegree => 16,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_BALANCESHEET_ITEM',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_BALANCESHEET_ITEM exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_BALANCESHEET_ITEM exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_CSM_ADJUSTMENTS_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_CSM_ADJUSTMENTS_HEADER',
|
||||||
pParallelDegree => 1
|
pParallelDegree => 1,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_CSM_ADJUSTMENTS_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_CSM_ADJ_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_CSM_ADJ_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -44,7 +46,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_CSM_ADJUSTMENTS_ITEM',
|
pFolderName => 'ARCHIVE/LM/LM_CSM_ADJUSTMENTS_ITEM',
|
||||||
pParallelDegree => 2
|
pParallelDegree => 2,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_CSM_ADJUSTMENTS_ITEM',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_CSM_ADJ_ITEM exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_CSM_ADJ_ITEM exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -64,7 +68,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_CSM_ADJUSTMENTS_ITEM_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_CSM_ADJUSTMENTS_ITEM_HEADER',
|
||||||
pParallelDegree => 2
|
pParallelDegree => 2,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_CSM_ADJUSTMENTS_ITEM_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_CSM_ADJ_ITEM_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_CSM_ADJ_ITEM_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_STANDING_FACILITIES',
|
pFolderName => 'ARCHIVE/LM/LM_STANDING_FACILITIES',
|
||||||
pParallelDegree => 8
|
pParallelDegree => 8,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_STANDING_FACILITY exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_STANDING_FACILITY exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -49,7 +51,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_STANDING_FACILITIES_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_STANDING_FACILITIES_HEADER',
|
||||||
pParallelDegree => 2
|
pParallelDegree => 2,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_STANDING_FACILITY_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_STANDING_FACILITY_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_CURRENT_ACCOUNTS_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_CURRENT_ACCOUNTS_HEADER',
|
||||||
pParallelDegree => 2
|
pParallelDegree => 2,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_CURRENT_ACCOUNTS_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_MRR_IND_CURRENT_ACCOUNT_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_MRR_IND_CURRENT_ACCOUNT_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -45,7 +47,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_CURRENT_ACCOUNTS_ITEM',
|
pFolderName => 'ARCHIVE/LM/LM_CURRENT_ACCOUNTS_ITEM',
|
||||||
pParallelDegree => 16
|
pParallelDegree => 16,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_CURRENT_ACCOUNTS_ITEM',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_MRR_IND_CURRENT_ACCOUNT_ITEM exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_MRR_IND_CURRENT_ACCOUNT_ITEM exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_FORECAST_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_FORECAST_HEADER',
|
||||||
pParallelDegree => 4
|
pParallelDegree => 4,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_FORECAST_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_FORECAST_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_FORECAST_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -49,7 +51,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_FORECAST_ITEM',
|
pFolderName => 'ARCHIVE/LM/LM_FORECAST_ITEM',
|
||||||
pParallelDegree => 16
|
pParallelDegree => 16,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_FORECAST_ITEM',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_FORECAST_ITEM exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_FORECAST_ITEM exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_QRE_ADJUSTMENTS_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_QRE_ADJUSTMENTS_HEADER',
|
||||||
pParallelDegree => 1
|
pParallelDegree => 1,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_QRE_ADJUSTMENTS_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_QR_ADJ_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_QR_ADJ_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -44,7 +46,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_QRE_ADJUSTMENTS_ITEM',
|
pFolderName => 'ARCHIVE/LM/LM_QRE_ADJUSTMENTS_ITEM',
|
||||||
pParallelDegree => 4
|
pParallelDegree => 4,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_QRE_ADJUSTMENTS_ITEM',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_QR_ADJ_ITEM exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_QR_ADJ_ITEM exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -64,7 +68,7 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_QRE_ADJUSTMENTS_ITEM_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_QRE_ADJUSTMENTS_ITEM_HEADER',
|
||||||
pParallelDegree => 2
|
pParallelDegree => 2, pTemplateTableName => 'CT_ET_TEMPLATES.LM_QRE_ADJUSTMENTS_ITEM_HEADER', pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_QR_ADJ_ITEM_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_QR_ADJ_ITEM_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_TTS_HEADER',
|
pFolderName => 'ARCHIVE/LM/LM_TTS_HEADER',
|
||||||
pParallelDegree => 1
|
pParallelDegree => 1,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_TTS_HEADER',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_TTS_HEADER exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_TTS_HEADER exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -44,7 +46,9 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/LM/LM_TTS_ITEM',
|
pFolderName => 'ARCHIVE/LM/LM_TTS_ITEM',
|
||||||
pParallelDegree => 1
|
pParallelDegree => 1,
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.LM_TTS_ITEM',
|
||||||
|
pJobClass => 'high'
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_TTS_ITEM exported');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_TTS_ITEM exported');
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|||||||
@@ -4,13 +4,12 @@
|
|||||||
# Confluence documentation (generated, not source)
|
# Confluence documentation (generated, not source)
|
||||||
confluence/
|
confluence/
|
||||||
|
|
||||||
|
patches/
|
||||||
# Log files from SPOOL operations
|
# Log files from SPOOL operations
|
||||||
log/
|
log/
|
||||||
*.log
|
|
||||||
|
|
||||||
# Test directories and files
|
# Test directories and files
|
||||||
test/
|
test/
|
||||||
*_test.sql
|
|
||||||
|
|
||||||
# Mock data scripts (development only)
|
# Mock data scripts (development only)
|
||||||
mock_data/
|
mock_data/
|
||||||
|
|||||||
@@ -10,22 +10,36 @@ PROMPT ========================================
|
|||||||
-- Add new columns
|
-- Add new columns
|
||||||
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD (
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD (
|
||||||
ARCHIVAL_STRATEGY VARCHAR2(30) DEFAULT 'THRESHOLD_BASED' NOT NULL,
|
ARCHIVAL_STRATEGY VARCHAR2(30) DEFAULT 'THRESHOLD_BASED' NOT NULL,
|
||||||
MINIMUM_AGE_MONTHS NUMBER(3) DEFAULT NULL
|
MINIMUM_AGE_MONTHS NUMBER(3) DEFAULT NULL,
|
||||||
|
IS_ARCHIVE_ENABLED CHAR(1) DEFAULT 'N' NOT NULL,
|
||||||
|
IS_KEEP_IN_TRASH CHAR(1) DEFAULT 'Y' NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Add check constraint for valid strategies
|
-- Add check constraints
|
||||||
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD CONSTRAINT
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD CONSTRAINT
|
||||||
CHK_ARCHIVAL_STRATEGY CHECK (
|
CHK_ARCHIVAL_STRATEGY CHECK (
|
||||||
ARCHIVAL_STRATEGY IN ('THRESHOLD_BASED', 'CURRENT_MONTH_ONLY', 'MINIMUM_AGE_MONTHS', 'HYBRID')
|
ARCHIVAL_STRATEGY IN ('THRESHOLD_BASED', 'MINIMUM_AGE_MONTHS', 'HYBRID')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD CONSTRAINT
|
||||||
|
CHK_IS_ARCHIVE_ENABLED CHECK (IS_ARCHIVE_ENABLED IN ('Y', 'N'));
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD CONSTRAINT
|
||||||
|
CHK_IS_KEEP_IN_TRASH CHECK (IS_KEEP_IN_TRASH IN ('Y', 'N'));
|
||||||
|
|
||||||
-- Add comments
|
-- Add comments
|
||||||
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVAL_STRATEGY IS
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVAL_STRATEGY IS
|
||||||
'Archival strategy: THRESHOLD_BASED (days), CURRENT_MONTH_ONLY (exclude current month), MINIMUM_AGE_MONTHS (minimum age), HYBRID (combination)';
|
'Archival strategy: THRESHOLD_BASED (days), MINIMUM_AGE_MONTHS (0=current month, N=retain N months), HYBRID (combination)';
|
||||||
|
|
||||||
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.MINIMUM_AGE_MONTHS IS
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.MINIMUM_AGE_MONTHS IS
|
||||||
'Minimum age in months for archival (used with MINIMUM_AGE_MONTHS or HYBRID strategies)';
|
'Minimum age in months for archival (used with MINIMUM_AGE_MONTHS or HYBRID strategies)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.IS_ARCHIVE_ENABLED IS
|
||||||
|
'Y=Enable archiving, N=Skip archiving. Controls if table participates in archival process. Added in MARS-828 v3.3.0';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.IS_KEEP_IN_TRASH IS
|
||||||
|
'Y=Keep files in TRASH after archiving, N=Delete immediately. Controls TRASH retention policy. Added in MARS-828 v3.3.0';
|
||||||
|
|
||||||
-- Verify columns added
|
-- Verify columns added
|
||||||
SELECT
|
SELECT
|
||||||
column_name,
|
column_name,
|
||||||
@@ -36,7 +50,7 @@ SELECT
|
|||||||
FROM all_tab_columns
|
FROM all_tab_columns
|
||||||
WHERE owner = 'CT_MRDS'
|
WHERE owner = 'CT_MRDS'
|
||||||
AND table_name = 'A_SOURCE_FILE_CONFIG'
|
AND table_name = 'A_SOURCE_FILE_CONFIG'
|
||||||
AND column_name IN ('ARCHIVAL_STRATEGY', 'MINIMUM_AGE_MONTHS')
|
AND column_name IN ('ARCHIVAL_STRATEGY', 'MINIMUM_AGE_MONTHS', 'IS_ARCHIVE_ENABLED', 'IS_KEEP_IN_TRASH')
|
||||||
ORDER BY column_id;
|
ORDER BY column_id;
|
||||||
|
|
||||||
PROMPT ========================================
|
PROMPT ========================================
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
-- MARS-828: Rename threshold columns for consistency
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-01-28
|
||||||
|
-- Description: Renames threshold columns to use consistent ARCHIVE_THRESHOLD_* prefix pattern
|
||||||
|
-- Old naming was inconsistent (DAYS_FOR vs FILES_COUNT_OVER)
|
||||||
|
-- New naming groups all threshold columns with common prefix
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT MARS-828: Renaming threshold columns for consistency
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
-- Rename threshold columns to consistent ARCHIVE_THRESHOLD_* pattern
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
RENAME COLUMN DAYS_FOR_ARCHIVE_THRESHOLD TO ARCHIVE_THRESHOLD_DAYS;
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
RENAME COLUMN FILES_COUNT_OVER_ARCHIVE_THRESHOLD TO ARCHIVE_THRESHOLD_FILES_COUNT;
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
RENAME COLUMN BYTES_SUM_OVER_ARCHIVE_THRESHOLD TO ARCHIVE_THRESHOLD_BYTES_SUM;
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
RENAME COLUMN ROWS_COUNT_OVER_ARCHIVE_THRESHOLD TO ARCHIVE_THRESHOLD_ROWS_COUNT;
|
||||||
|
|
||||||
|
-- Verify column renames
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT Verifying threshold column renames...
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
column_name,
|
||||||
|
data_type,
|
||||||
|
data_length
|
||||||
|
FROM all_tab_columns
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name = 'A_SOURCE_FILE_CONFIG'
|
||||||
|
AND column_name LIKE 'ARCHIVE_THRESHOLD%'
|
||||||
|
ORDER BY column_id;
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT Expected columns:
|
||||||
|
PROMPT ARCHIVE_THRESHOLD_DAYS
|
||||||
|
PROMPT ARCHIVE_THRESHOLD_FILES_COUNT
|
||||||
|
PROMPT ARCHIVE_THRESHOLD_BYTES_SUM
|
||||||
|
PROMPT ARCHIVE_THRESHOLD_ROWS_COUNT
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
PROMPT Threshold columns renamed successfully
|
||||||
|
PROMPT ========================================
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
-- =====================================================================
|
||||||
|
-- Script: 01b_MARS_828_add_column_comments.sql
|
||||||
|
-- MARS Issue: MARS-828
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-20
|
||||||
|
-- Purpose: Add comprehensive column comments for A_SOURCE_FILE_CONFIG and A_SOURCE_FILE_RECEIVED tables
|
||||||
|
-- Description: Documents all columns to improve database maintainability and user understanding
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT MARS-828: Adding comprehensive column comments
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- A_SOURCE_FILE_CONFIG Column Comments
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT Adding column comments for A_SOURCE_FILE_CONFIG...
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY IS
|
||||||
|
'Primary key - unique identifier for source file configuration record';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_KEY IS
|
||||||
|
'Foreign key to A_SOURCE table - identifies the source system (e.g., LM, C2D, CSDB)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE IS
|
||||||
|
'Type of file configuration: INPUT (data files), CONTAINER (xml files), or LOAD_CONFIG (configuration files)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID IS
|
||||||
|
'Unique identifier for the source file within the source system (e.g., UC_DISSEM, STANDING_FACILITIES)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_DESC IS
|
||||||
|
'Human-readable description of the source file and its purpose';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_NAME_PATTERN IS
|
||||||
|
'Filename pattern for matching incoming files (supports wildcards, e.g., UC_NMA_DISSEM-*.csv)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID IS
|
||||||
|
'Identifier for the target table where data will be loaded (without schema prefix)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.TEMPLATE_TABLE_NAME IS
|
||||||
|
'Fully qualified name of template table in CT_ET_TEMPLATES schema used for external table creation';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.CONTAINER_FILE_KEY IS
|
||||||
|
'Foreign key to parent container configuration when this file is part of an xml (NULL for standalone files)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_DAYS IS
|
||||||
|
'Threshold for THRESHOLD_BASED strategy: archive data older than N days';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_FILES_COUNT IS
|
||||||
|
'Trigger archival when file count exceeds this threshold (used in THRESHOLD_BASED and HYBRID strategies)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_BYTES_SUM IS
|
||||||
|
'Trigger archival when total size in bytes exceeds this threshold (used in THRESHOLD_BASED and HYBRID strategies)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_ROWS_COUNT IS
|
||||||
|
'Trigger archival when total row count exceeds this threshold (used in THRESHOLD_BASED and HYBRID strategies)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ODS_SCHEMA_NAME IS
|
||||||
|
'Schema name where ODS external tables are created (typically ODS)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.HOURS_TO_EXPIRE_STATISTICS IS
|
||||||
|
'Number of hours before table statistics expire and need to be recalculated';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVAL_STRATEGY IS
|
||||||
|
'Archival strategy: THRESHOLD_BASED (days-based), MINIMUM_AGE_MONTHS (0=current month, N=retain N months), HYBRID (combination)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.MINIMUM_AGE_MONTHS IS
|
||||||
|
'Minimum age in months before archival (required for MINIMUM_AGE_MONTHS and HYBRID strategies, 0=current month only)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING IS
|
||||||
|
'Oracle character set name for CSV files (e.g., UTF8, WE8MSWIN1252, EE8ISO8859P2)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.IS_ARCHIVE_ENABLED IS
|
||||||
|
'Y=Enable archiving, N=Skip archiving. Controls if table participates in archival process';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.IS_KEEP_IN_TRASH IS
|
||||||
|
'Y=Keep files in TRASH after archiving, N=Delete immediately. Controls TRASH retention policy';
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- A_SOURCE_FILE_RECEIVED Column Comments
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT Adding column comments for A_SOURCE_FILE_RECEIVED...
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY IS
|
||||||
|
'Primary key - unique identifier for received file record';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_CONFIG_KEY IS
|
||||||
|
'Foreign key to A_SOURCE_FILE_CONFIG - links file to its configuration and processing rules';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.SOURCE_FILE_NAME IS
|
||||||
|
'Full object name/path of the received file in OCI Object Storage (includes INBOX prefix)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.CHECKSUM IS
|
||||||
|
'MD5 checksum of file content for integrity verification and duplicate detection';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.CREATED IS
|
||||||
|
'Timestamp with timezone when file was created/uploaded to Object Storage (from DBMS_CLOUD.LIST_OBJECTS)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.BYTES IS
|
||||||
|
'File size in bytes';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.RECEPTION_DATE IS
|
||||||
|
'Date when file was registered in the system (extracted from CREATED timestamp)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PROCESSING_STATUS IS
|
||||||
|
'Current processing status: RECEIVED → VALIDATED → READY_FOR_INGESTION → INGESTED → ARCHIVED_AND_TRASHED → ARCHIVED_AND_PURGED';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.EXTERNAL_TABLE_NAME IS
|
||||||
|
'Name of temporary external table created for file validation (dropped after validation)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PARTITION_YEAR IS
|
||||||
|
'Year partition value (YYYY format) when file was archived to ARCHIVE bucket with Hive-style partitioning';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PARTITION_MONTH IS
|
||||||
|
'Month partition value (MM format) when file was archived to ARCHIVE bucket with Hive-style partitioning';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.ARCH_PATH IS
|
||||||
|
'Archive directory prefix in ARCHIVE bucket containing archived Parquet files (supports multiple files from parallel DBMS_CLOUD.EXPORT_DATA)';
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- Verification
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Verifying column comments...
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
table_name,
|
||||||
|
COUNT(*) as total_columns,
|
||||||
|
COUNT(comments) as documented_columns,
|
||||||
|
COUNT(*) - COUNT(comments) as undocumented_columns
|
||||||
|
FROM all_col_comments
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name IN ('A_SOURCE_FILE_CONFIG', 'A_SOURCE_FILE_RECEIVED')
|
||||||
|
GROUP BY table_name
|
||||||
|
ORDER BY table_name;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Detailed column documentation status:
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
table_name,
|
||||||
|
column_name,
|
||||||
|
CASE WHEN comments IS NULL THEN 'MISSING' ELSE 'OK' END as comment_status
|
||||||
|
FROM all_col_comments
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name IN ('A_SOURCE_FILE_CONFIG', 'A_SOURCE_FILE_RECEIVED')
|
||||||
|
ORDER BY table_name, column_name;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT Column comments added successfully
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT A_SOURCE_FILE_CONFIG: All 20 columns documented
|
||||||
|
PROMPT A_SOURCE_FILE_RECEIVED: All 12 columns documented
|
||||||
|
PROMPT ========================================
|
||||||
@@ -1,14 +1,29 @@
|
|||||||
-- ===================================================================
|
--=============================================================================================================================
|
||||||
-- MARS-828: Install FILE_ARCHIVER Package Specification v3.0.0
|
-- MARS-828: Install CT_MRDS.FILE_ARCHIVER Package Specification v3.3.0
|
||||||
-- ===================================================================
|
--=============================================================================================================================
|
||||||
-- Purpose: Deploy updated package specification with version 3.0.0
|
-- Purpose: Deploy FILE_ARCHIVER Package Specification with FN_ function names
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2026-01-27
|
-- Date: 2026-02-11
|
||||||
-- ===================================================================
|
-- Related: MARS-828 Archival Strategy Implementation
|
||||||
|
--=============================================================================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON
|
||||||
|
|
||||||
|
PROMPT ========================================================================
|
||||||
|
PROMPT Installing CT_MRDS.FILE_ARCHIVER Package Specification v3.3.0
|
||||||
|
PROMPT ========================================================================
|
||||||
|
|
||||||
@@new_version/FILE_ARCHIVER.pkg
|
@@new_version/FILE_ARCHIVER.pkg
|
||||||
|
|
||||||
|
-- Verify package compilation (check specific schema when installing as ADMIN)
|
||||||
|
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
|
||||||
|
FROM ALL_OBJECTS
|
||||||
|
WHERE OWNER = 'CT_MRDS'
|
||||||
|
AND OBJECT_NAME = 'FILE_ARCHIVER'
|
||||||
|
AND OBJECT_TYPE = 'PACKAGE';
|
||||||
|
|
||||||
PROMPT ========================================
|
PROMPT SUCCESS: FILE_ARCHIVER Package Specification v3.3.0 installed
|
||||||
PROMPT FILE_ARCHIVER Specification v3.0.0 ready for installation
|
|
||||||
PROMPT ========================================
|
--=============================================================================================================================
|
||||||
|
-- End of Script
|
||||||
|
--=============================================================================================================================
|
||||||
|
|||||||
@@ -1,14 +1,38 @@
|
|||||||
-- ===================================================================
|
--=============================================================================================================================
|
||||||
-- MARS-828: Install FILE_ARCHIVER Package Body v3.0.0
|
-- MARS-828: Install CT_MRDS.FILE_ARCHIVER Package Body v3.3.0
|
||||||
-- ===================================================================
|
--=============================================================================================================================
|
||||||
-- Purpose: Deploy updated package body with GET_ARCHIVAL_WHERE_CLAUSE function
|
-- Purpose: Deploy FILE_ARCHIVER Package Body with config-based archival and FN_ function names
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2026-01-27
|
-- Date: 2026-02-11
|
||||||
-- Changes:
|
-- Related: MARS-828 Archival Strategy Implementation
|
||||||
-- - Added GET_ARCHIVAL_WHERE_CLAUSE private function
|
--=============================================================================================================================
|
||||||
-- - Updated ARCHIVE_TABLE_DATA to use strategy-based filtering
|
|
||||||
-- - Updated GATHER_TABLE_STAT to use strategy-based statistics
|
SET SERVEROUTPUT ON
|
||||||
-- ===================================================================
|
|
||||||
|
PROMPT ========================================================================
|
||||||
|
PROMPT Installing CT_MRDS.FILE_ARCHIVER Package Body v3.3.0
|
||||||
|
PROMPT ========================================================================
|
||||||
|
|
||||||
@@new_version/FILE_ARCHIVER.pkb
|
@@new_version/FILE_ARCHIVER.pkb
|
||||||
|
|
||||||
|
-- Verify package compilation (check specific schema when installing as ADMIN)
|
||||||
|
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
|
||||||
|
FROM ALL_OBJECTS
|
||||||
|
WHERE OWNER = 'CT_MRDS'
|
||||||
|
AND OBJECT_NAME = 'FILE_ARCHIVER'
|
||||||
|
AND OBJECT_TYPE IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
|
ORDER BY OBJECT_TYPE;
|
||||||
|
|
||||||
|
-- Check for any compilation errors
|
||||||
|
SELECT 'COMPILATION ERRORS FOUND' AS WARNING
|
||||||
|
FROM ALL_ERRORS
|
||||||
|
WHERE OWNER = 'CT_MRDS'
|
||||||
|
AND NAME = 'FILE_ARCHIVER'
|
||||||
|
AND TYPE = 'PACKAGE BODY'
|
||||||
|
AND ROWNUM = 1;
|
||||||
|
|
||||||
|
PROMPT SUCCESS: FILE_ARCHIVER Package Body v3.3.0 installed
|
||||||
|
|
||||||
|
--=============================================================================================================================
|
||||||
|
-- End of Script
|
||||||
|
--=============================================================================================================================
|
||||||
|
|||||||
@@ -59,9 +59,23 @@ WHERE owner = 'CT_MRDS'
|
|||||||
AND object_type IN ('PACKAGE', 'PACKAGE BODY')
|
AND object_type IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
ORDER BY object_type;
|
ORDER BY object_type;
|
||||||
|
|
||||||
-- 5. Check for compilation errors
|
-- 5. Check FILE_MANAGER package compilation status
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT 5. Checking for compilation errors...
|
PROMPT 5. Checking FILE_MANAGER package status...
|
||||||
|
SELECT
|
||||||
|
object_name,
|
||||||
|
object_type,
|
||||||
|
status,
|
||||||
|
TO_CHAR(last_ddl_time, 'YYYY-MM-DD HH24:MI:SS') as last_ddl_time
|
||||||
|
FROM all_objects
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND object_name = 'FILE_MANAGER'
|
||||||
|
AND object_type IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
|
ORDER BY object_type;
|
||||||
|
|
||||||
|
-- 6. Check for compilation errors
|
||||||
|
PROMPT
|
||||||
|
PROMPT 6. Checking for compilation errors (FILE_ARCHIVER)...
|
||||||
SELECT
|
SELECT
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
@@ -73,14 +87,33 @@ WHERE owner = 'CT_MRDS'
|
|||||||
AND name = 'FILE_ARCHIVER'
|
AND name = 'FILE_ARCHIVER'
|
||||||
ORDER BY type, sequence;
|
ORDER BY type, sequence;
|
||||||
|
|
||||||
-- 6. Verify package version
|
-- 7. Check for compilation errors (FILE_MANAGER)
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT 6. Verifying FILE_ARCHIVER version...
|
PROMPT 7. Checking for compilation errors (FILE_MANAGER)...
|
||||||
SELECT CT_MRDS.FILE_ARCHIVER.GET_VERSION() as package_version FROM DUAL;
|
SELECT
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
line,
|
||||||
|
position,
|
||||||
|
text
|
||||||
|
FROM all_errors
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND name = 'FILE_MANAGER'
|
||||||
|
ORDER BY type, sequence;
|
||||||
|
|
||||||
-- 7. Test trigger validation
|
-- 8. Verify package versions
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT 7. Testing trigger validation (should fail)...
|
PROMPT 8. Verifying package versions...
|
||||||
|
PROMPT FILE_ARCHIVER version:
|
||||||
|
SELECT CT_MRDS.FILE_ARCHIVER.GET_VERSION() as package_version FROM DUAL;
|
||||||
|
PROMPT FILE_MANAGER version:
|
||||||
|
SELECT CT_MRDS.FILE_MANAGER.GET_VERSION() as package_version FROM DUAL;
|
||||||
|
|
||||||
|
-- 9. Test trigger validation
|
||||||
|
PROMPT
|
||||||
|
PROMPT 9. Testing trigger validation (should fail)...
|
||||||
|
WHENEVER SQLERROR CONTINUE
|
||||||
|
SET SERVEROUTPUT ON
|
||||||
DECLARE
|
DECLARE
|
||||||
vTestPassed BOOLEAN := FALSE;
|
vTestPassed BOOLEAN := FALSE;
|
||||||
BEGIN
|
BEGIN
|
||||||
@@ -107,14 +140,16 @@ EXCEPTION
|
|||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
IF SQLCODE = -20999 THEN
|
IF SQLCODE = -20999 THEN
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: Trigger validation working correctly');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: Trigger validation working correctly');
|
||||||
DBMS_OUTPUT.PUT_LINE('Expected error: ' || SQLERRM);
|
DBMS_OUTPUT.PUT_LINE('Trigger correctly rejected MINIMUM_AGE_MONTHS strategy without required value');
|
||||||
vTestPassed := TRUE;
|
vTestPassed := TRUE;
|
||||||
ELSE
|
ELSE
|
||||||
DBMS_OUTPUT.PUT_LINE('ERROR: Unexpected error: ' || SQLERRM);
|
DBMS_OUTPUT.PUT_LINE('ERROR: Unexpected error occurred during trigger validation');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
|
||||||
END IF;
|
END IF;
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
END;
|
END;
|
||||||
/
|
/
|
||||||
|
WHENEVER SQLERROR EXIT FAILURE
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT ========================================
|
PROMPT ========================================
|
||||||
|
|||||||
@@ -0,0 +1,350 @@
|
|||||||
|
-- =====================================================================
|
||||||
|
-- Script: 06_MARS_828_configure_release01_tables.sql
|
||||||
|
-- MARS Issue: MARS-828
|
||||||
|
-- Purpose: Configure COMPLETE archival parameters for Release 01 tables
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-05
|
||||||
|
--
|
||||||
|
-- Description:
|
||||||
|
-- Configures ALL archival parameters for 25 tables:
|
||||||
|
-- - ARCHIVAL_STRATEGY and MINIMUM_AGE_MONTHS
|
||||||
|
-- - Archival triggers (FILES/ROWS/BYTES thresholds)
|
||||||
|
-- - Statistics expiration (HOURS_TO_EXPIRE_STATISTICS)
|
||||||
|
--
|
||||||
|
-- Configuration by group:
|
||||||
|
-- - 19 LM tables: MINIMUM_AGE_MONTHS=0 (current month only), 10 files OR 100K rows OR 1GB, 24h stats
|
||||||
|
-- - 2 CSDB DEBT: MINIMUM_AGE_MONTHS=0 (current month only), 5 files OR 50K rows OR 512MB, 48h stats
|
||||||
|
-- - 4 CSDB ratings: MINIMUM_AGE_MONTHS=0 (current month only), 10 files OR 20K rows OR 256MB, 72h stats
|
||||||
|
--
|
||||||
|
-- Dependencies:
|
||||||
|
-- - A_SOURCE_FILE_CONFIG table with all archival columns
|
||||||
|
-- - TRG_BI_A_SRC_FILE_CFG_ARCH_VAL trigger
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT MARS-828: Enhanced Configuration - Complete Archival Parameters
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT
|
||||||
|
PROMPT This script configures COMPLETE archival parameters for 25 tables
|
||||||
|
PROMPT
|
||||||
|
PROMPT LM Tables (19):
|
||||||
|
PROMPT - Strategy: MINIMUM_AGE_MONTHS = 0 (current month only)
|
||||||
|
PROMPT - Triggers: 10 files OR 100,000 rows OR 1 GB
|
||||||
|
PROMPT - Stats Expiration: 24 hours
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB DEBT Tables (2):
|
||||||
|
PROMPT - Strategy: MINIMUM_AGE_MONTHS = 0 (current month only)
|
||||||
|
PROMPT - Triggers: 5 files OR 50,000 rows OR 512 MB
|
||||||
|
PROMPT - Stats Expiration: 48 hours
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB Rating/Description Tables (4):
|
||||||
|
PROMPT - Strategy: MINIMUM_AGE_MONTHS = 0 (current month only)
|
||||||
|
PROMPT - Triggers: 10 files OR 20,000 rows OR 256 MB
|
||||||
|
PROMPT - Stats Expiration: 72 hours
|
||||||
|
PROMPT
|
||||||
|
PROMPT Current timestamp:
|
||||||
|
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS CURRENT_TIME FROM DUAL;
|
||||||
|
PROMPT
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT SECTION 1: LM Tables Configuration (MINIMUM_AGE_MONTHS = 0)
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Thresholds: 10 files OR 100K rows OR 1GB
|
||||||
|
PROMPT Stats expire: 24 hours
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
-- Update all 19 LM tables in a single statement
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 0, -- 0 = current month only
|
||||||
|
ODS_SCHEMA_NAME = 'ODS',
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT = 10,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT = 100000,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM = 1073741824, -- 1 GB
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS = 24,
|
||||||
|
IS_ARCHIVE_ENABLED = 'Y', -- Enable archival for all LM tables
|
||||||
|
IS_KEEP_IN_TRASH = 'N' -- Delete files immediately after archival (no TRASH retention)
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND A_SOURCE_KEY = 'LM'
|
||||||
|
AND TABLE_ID IN (
|
||||||
|
'LM_STANDING_FACILITIES',
|
||||||
|
'LM_STANDING_FACILITIES_HEADER',
|
||||||
|
'LM_TTS_HEADER',
|
||||||
|
'LM_TTS_ITEM',
|
||||||
|
'LM_ADHOC_ADJUSTMENTS_HEADER',
|
||||||
|
'LM_ADHOC_ADJUSTMENTS_ITEM',
|
||||||
|
'LM_ADHOC_ADJUSTMENTS_ITEM_HEADER',
|
||||||
|
'LM_BALANCESHEET_HEADER',
|
||||||
|
'LM_BALANCESHEET_ITEM',
|
||||||
|
'LM_CSM_ADJUSTMENTS_HEADER',
|
||||||
|
'LM_CSM_ADJUSTMENTS_ITEM',
|
||||||
|
'LM_CSM_ADJUSTMENTS_ITEM_HEADER',
|
||||||
|
'LM_CURRENT_ACCOUNTS_HEADER',
|
||||||
|
'LM_CURRENT_ACCOUNTS_ITEM',
|
||||||
|
'LM_FORECAST_HEADER',
|
||||||
|
'LM_FORECAST_ITEM',
|
||||||
|
'LM_QRE_ADJUSTMENTS_HEADER',
|
||||||
|
'LM_QRE_ADJUSTMENTS_ITEM',
|
||||||
|
'LM_QRE_ADJUSTMENTS_ITEM_HEADER'
|
||||||
|
);
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT LM tables configuration completed
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT SECTION 2: CSDB DEBT Tables (MINIMUM_AGE_MONTHS = 0)
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Thresholds: 5 files OR 50K rows OR 512MB
|
||||||
|
PROMPT Stats expire: 48 hours
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
-- Update CSDB DEBT tables (current month only)
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 0,
|
||||||
|
ODS_SCHEMA_NAME = 'ODS',
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT = 5,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT = 50000,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM = 536870912, -- 512 MB
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS = 48,
|
||||||
|
IS_ARCHIVE_ENABLED = 'Y', -- Enable archival for CSDB DEBT tables
|
||||||
|
IS_KEEP_IN_TRASH = 'N' -- Delete files immediately after archival (no TRASH retention)
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND A_SOURCE_KEY = 'CSDB'
|
||||||
|
AND TABLE_ID IN ('CSDB_DEBT', 'CSDB_DEBT_DAILY');
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB DEBT tables configuration completed
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT SECTION 3: CSDB Rating/Description Tables (MINIMUM_AGE_MONTHS = 0)
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Thresholds: 10 files OR 20K rows OR 256MB
|
||||||
|
PROMPT Stats expire: 72 hours
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
-- Update CSDB rating/description tables
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 0, -- 0 = current month only
|
||||||
|
ODS_SCHEMA_NAME = 'ODS',
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT = 10,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT = 20000,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM = 268435456, -- 256 MB
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS = 72,
|
||||||
|
IS_ARCHIVE_ENABLED = 'Y', -- Enable archival for CSDB rating/description tables
|
||||||
|
IS_KEEP_IN_TRASH = 'N' -- Delete files immediately after archival (no TRASH retention)
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND A_SOURCE_KEY = 'CSDB'
|
||||||
|
AND TABLE_ID IN (
|
||||||
|
'CSDB_INSTR_RAT_FULL',
|
||||||
|
'CSDB_INSTR_DESC_FULL',
|
||||||
|
'CSDB_ISSUER_RAT_FULL',
|
||||||
|
'CSDB_ISSUER_DESC_FULL'
|
||||||
|
);
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB rating/description tables configuration completed
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Committing configuration changes...
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Configuration committed successfully.
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT VERIFICATION: Complete Archival Configuration
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT LM Tables (MINIMUM_AGE_MONTHS = 0):
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT AS FILE_THR,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT AS ROW_THR,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
IS_ARCHIVE_ENABLED,
|
||||||
|
IS_KEEP_IN_TRASH,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS'
|
||||||
|
AND MINIMUM_AGE_MONTHS = 0
|
||||||
|
AND ARCHIVE_THRESHOLD_FILES_COUNT = 10
|
||||||
|
AND ARCHIVE_THRESHOLD_ROWS_COUNT = 100000
|
||||||
|
AND ARCHIVE_THRESHOLD_BYTES_SUM = 1073741824
|
||||||
|
AND HOURS_TO_EXPIRE_STATISTICS = 24
|
||||||
|
AND IS_ARCHIVE_ENABLED = 'Y'
|
||||||
|
AND IS_KEEP_IN_TRASH = 'N'
|
||||||
|
THEN 'OK'
|
||||||
|
ELSE 'ERROR'
|
||||||
|
END AS STATUS
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE A_SOURCE_KEY = 'LM'
|
||||||
|
AND SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND TABLE_ID LIKE 'LM_%'
|
||||||
|
ORDER BY TABLE_ID;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB DEBT Tables (MINIMUM_AGE_MONTHS = 0):
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT AS FILE_THR,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT AS ROW_THR,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
IS_ARCHIVE_ENABLED,
|
||||||
|
IS_KEEP_IN_TRASH,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS'
|
||||||
|
AND MINIMUM_AGE_MONTHS = 0
|
||||||
|
AND ARCHIVE_THRESHOLD_FILES_COUNT = 5
|
||||||
|
AND ARCHIVE_THRESHOLD_ROWS_COUNT = 50000
|
||||||
|
AND ARCHIVE_THRESHOLD_BYTES_SUM = 536870912
|
||||||
|
AND HOURS_TO_EXPIRE_STATISTICS = 48
|
||||||
|
AND IS_ARCHIVE_ENABLED = 'Y'
|
||||||
|
AND IS_KEEP_IN_TRASH = 'N'
|
||||||
|
THEN 'OK'
|
||||||
|
ELSE 'ERROR'
|
||||||
|
END AS STATUS
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE A_SOURCE_KEY = 'CSDB'
|
||||||
|
AND SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND TABLE_ID IN ('CSDB_DEBT', 'CSDB_DEBT_DAILY')
|
||||||
|
ORDER BY TABLE_ID;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB Rating/Description Tables (MINIMUM_AGE_MONTHS = 0):
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT AS FILE_THR,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT AS ROW_THR,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
IS_ARCHIVE_ENABLED,
|
||||||
|
IS_KEEP_IN_TRASH,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS'
|
||||||
|
AND MINIMUM_AGE_MONTHS = 0
|
||||||
|
AND ARCHIVE_THRESHOLD_FILES_COUNT = 10
|
||||||
|
AND ARCHIVE_THRESHOLD_ROWS_COUNT = 20000
|
||||||
|
AND ARCHIVE_THRESHOLD_BYTES_SUM = 268435456
|
||||||
|
AND HOURS_TO_EXPIRE_STATISTICS = 72
|
||||||
|
AND IS_ARCHIVE_ENABLED = 'Y'
|
||||||
|
AND IS_KEEP_IN_TRASH = 'N'
|
||||||
|
THEN 'OK'
|
||||||
|
ELSE 'ERROR'
|
||||||
|
END AS STATUS
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE A_SOURCE_KEY = 'CSDB'
|
||||||
|
AND SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND TABLE_ID IN ('CSDB_INSTR_RAT_FULL', 'CSDB_INSTR_DESC_FULL', 'CSDB_ISSUER_RAT_FULL', 'CSDB_ISSUER_DESC_FULL')
|
||||||
|
ORDER BY TABLE_ID;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Summary: Total Configured Tables with Full Parameters
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
COUNT(*) AS TOTAL_CONFIGURED,
|
||||||
|
SUM(CASE WHEN MINIMUM_AGE_MONTHS = 0 THEN 1 ELSE 0 END) AS CURRENT_MONTH_ONLY,
|
||||||
|
SUM(CASE WHEN MINIMUM_AGE_MONTHS > 0 THEN 1 ELSE 0 END) AS MULTI_MONTH_RETENTION,
|
||||||
|
SUM(CASE WHEN ARCHIVE_THRESHOLD_FILES_COUNT IS NOT NULL THEN 1 ELSE 0 END) AS WITH_FILE_THRESHOLD,
|
||||||
|
SUM(CASE WHEN ARCHIVE_THRESHOLD_ROWS_COUNT IS NOT NULL THEN 1 ELSE 0 END) AS WITH_ROWS_THRESHOLD,
|
||||||
|
SUM(CASE WHEN ARCHIVE_THRESHOLD_BYTES_SUM IS NOT NULL THEN 1 ELSE 0 END) AS WITH_BYTES_THRESHOLD,
|
||||||
|
SUM(CASE WHEN HOURS_TO_EXPIRE_STATISTICS IS NOT NULL THEN 1 ELSE 0 END) AS WITH_STATS_EXPIRY,
|
||||||
|
SUM(CASE WHEN IS_ARCHIVE_ENABLED = 'Y' THEN 1 ELSE 0 END) AS ARCHIVAL_ENABLED,
|
||||||
|
SUM(CASE WHEN IS_KEEP_IN_TRASH = 'N' THEN 1 ELSE 0 END) AS IMMEDIATE_DELETE
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND ((A_SOURCE_KEY = 'LM' AND TABLE_ID LIKE 'LM_%')
|
||||||
|
OR (A_SOURCE_KEY = 'CSDB' AND TABLE_ID IN (
|
||||||
|
'CSDB_DEBT', 'CSDB_DEBT_DAILY',
|
||||||
|
'CSDB_INSTR_RAT_FULL', 'CSDB_INSTR_DESC_FULL',
|
||||||
|
'CSDB_ISSUER_RAT_FULL', 'CSDB_ISSUER_DESC_FULL'
|
||||||
|
)));
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Expected:
|
||||||
|
PROMPT - TOTAL_CONFIGURED = 25
|
||||||
|
PROMPT - WITH_FILE_THRESHOLD = 25
|
||||||
|
PROMPT - WITH_ROWS_THRESHOLD = 25
|
||||||
|
PROMPT - WITH_BYTES_THRESHOLD = 25
|
||||||
|
PROMPT - WITH_STATS_EXPIRY = 25
|
||||||
|
PROMPT - ARCHIVAL_ENABLED = 25 (all tables enabled for archival)
|
||||||
|
PROMPT - IMMEDIATE_DELETE = 25 (all tables delete files immediately, no TRASH retention)
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Parameter Configuration Summary by Group
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
CASE
|
||||||
|
WHEN A_SOURCE_KEY = 'LM' THEN 'LM Tables'
|
||||||
|
WHEN TABLE_ID LIKE 'CSDB_DEBT%' THEN 'CSDB DEBT'
|
||||||
|
ELSE 'CSDB Ratings'
|
||||||
|
END AS GROUP_NAME,
|
||||||
|
COUNT(*) AS TABLE_COUNT,
|
||||||
|
MAX(ARCHIVAL_STRATEGY) AS STRATEGY,
|
||||||
|
MAX(MINIMUM_AGE_MONTHS) AS MIN_AGE,
|
||||||
|
MAX(ARCHIVE_THRESHOLD_FILES_COUNT) AS FILES_THRESHOLD,
|
||||||
|
MAX(ARCHIVE_THRESHOLD_ROWS_COUNT) AS ROWS_THRESHOLD,
|
||||||
|
ROUND(MAX(ARCHIVE_THRESHOLD_BYTES_SUM)/1048576, 0) || ' MB' AS BYTES_THRESHOLD,
|
||||||
|
MAX(HOURS_TO_EXPIRE_STATISTICS) AS STATS_HOURS
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND ((A_SOURCE_KEY = 'LM' AND TABLE_ID LIKE 'LM_%')
|
||||||
|
OR (A_SOURCE_KEY = 'CSDB' AND TABLE_ID IN (
|
||||||
|
'CSDB_DEBT', 'CSDB_DEBT_DAILY',
|
||||||
|
'CSDB_INSTR_RAT_FULL', 'CSDB_INSTR_DESC_FULL',
|
||||||
|
'CSDB_ISSUER_RAT_FULL', 'CSDB_ISSUER_DESC_FULL'
|
||||||
|
)))
|
||||||
|
GROUP BY
|
||||||
|
CASE
|
||||||
|
WHEN A_SOURCE_KEY = 'LM' THEN 'LM Tables'
|
||||||
|
WHEN TABLE_ID LIKE 'CSDB_DEBT%' THEN 'CSDB DEBT'
|
||||||
|
ELSE 'CSDB Ratings'
|
||||||
|
END
|
||||||
|
ORDER BY GROUP_NAME;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Configuration Complete
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT
|
||||||
|
PROMPT Next Steps:
|
||||||
|
PROMPT 1. Review verification results above
|
||||||
|
PROMPT 2. All 25 tables should show STATUS = 'OK'
|
||||||
|
PROMPT 3. Verify parameter configuration summary matches expectations
|
||||||
|
PROMPT 4. Monitor archival process with new thresholds
|
||||||
|
PROMPT
|
||||||
|
PROMPT Archival Trigger Logic (OR condition):
|
||||||
|
PROMPT - Archival starts when ANY threshold is exceeded
|
||||||
|
PROMPT - Example: 10 files OR 100K rows OR 1GB triggers archival
|
||||||
|
PROMPT
|
||||||
|
PROMPT Statistics Refresh:
|
||||||
|
PROMPT - LM: Every 24 hours (daily updates for frequent changes)
|
||||||
|
PROMPT - CSDB DEBT: Every 48 hours (bi-daily for larger datasets)
|
||||||
|
PROMPT - CSDB Ratings: Every 72 hours (every 3 days for stable data)
|
||||||
|
PROMPT
|
||||||
|
PROMPT Log file: 06_MARS_828_configure_release01_tables.log
|
||||||
|
PROMPT =====================================================================
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
-- MARS-828: Add TRASH retention statuses to A_SOURCE_FILE_RECEIVED
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-09
|
||||||
|
-- Description: Adds ARCHIVED_AND_TRASHED and ARCHIVED_AND_PURGED statuses to support TRASH retention feature
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT MARS-828: Adding TRASH retention statuses
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
-- Drop old constraint
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED DROP CONSTRAINT A_SOURCE_FILE_RECEIVED_CHK;
|
||||||
|
|
||||||
|
-- Add new constraint with TRASH retention statuses
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED ADD CONSTRAINT A_SOURCE_FILE_RECEIVED_CHK
|
||||||
|
CHECK (PROCESSING_STATUS IN (
|
||||||
|
'RECEIVED',
|
||||||
|
'VALIDATED',
|
||||||
|
'VALIDATION_FAILED',
|
||||||
|
'READY_FOR_INGESTION',
|
||||||
|
'INGESTED',
|
||||||
|
'ARCHIVED', -- Legacy status (backward compatibility)
|
||||||
|
'ARCHIVED_AND_TRASHED', -- Files archived to Parquet and kept in TRASH folder (DATA bucket subfolder)
|
||||||
|
'ARCHIVED_AND_PURGED' -- Files archived to Parquet and deleted from TRASH folder
|
||||||
|
));
|
||||||
|
|
||||||
|
-- Add comment
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PROCESSING_STATUS IS
|
||||||
|
'File processing status: RECEIVED → VALIDATED → READY_FOR_INGESTION → INGESTED → ARCHIVED_AND_TRASHED → ARCHIVED_AND_PURGED (optional)';
|
||||||
|
|
||||||
|
-- Verify constraint
|
||||||
|
SELECT constraint_name, constraint_type, search_condition
|
||||||
|
FROM user_constraints
|
||||||
|
WHERE table_name = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND constraint_name = 'A_SOURCE_FILE_RECEIVED_CHK';
|
||||||
|
|
||||||
|
-- Show current status distribution
|
||||||
|
SELECT PROCESSING_STATUS, COUNT(*) as FILE_COUNT
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
GROUP BY PROCESSING_STATUS
|
||||||
|
ORDER BY PROCESSING_STATUS;
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT TRASH retention statuses added successfully
|
||||||
|
PROMPT Status flow: INGESTED → ARCHIVED_AND_TRASHED → ARCHIVED_AND_PURGED (optional)
|
||||||
|
PROMPT Legacy ARCHIVED status maintained for backward compatibility
|
||||||
|
PROMPT ========================================
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
-- MARS-828: Grant EXECUTE privilege on T_FILENAME to MRDS_LOADER
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-17
|
||||||
|
-- Description: Grants EXECUTE privilege on CT_MRDS.T_FILENAME type to MRDS_LOADER user for file processing operations
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT MARS-828: Granting EXECUTE on T_FILENAME
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
-- Grant EXECUTE privilege
|
||||||
|
GRANT EXECUTE ON CT_MRDS.T_FILENAME TO MRDS_LOADER;
|
||||||
|
|
||||||
|
PROMPT EXECUTE privilege on CT_MRDS.T_FILENAME granted to MRDS_LOADER
|
||||||
|
|
||||||
|
-- Verify grant
|
||||||
|
SELECT GRANTEE, PRIVILEGE, GRANTABLE
|
||||||
|
FROM USER_TAB_PRIVS
|
||||||
|
WHERE TABLE_NAME = 'T_FILENAME'
|
||||||
|
AND GRANTEE = 'MRDS_LOADER';
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT T_FILENAME privilege grant completed
|
||||||
|
PROMPT ========================================
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
--=============================================================================================================================
|
||||||
|
-- MARS-828: Install CT_MRDS.FILE_MANAGER Package Specification v3.3.2
|
||||||
|
--=============================================================================================================================
|
||||||
|
-- Purpose: Deploy FILE_MANAGER Package Specification with MARS-828 column compatibility
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-20
|
||||||
|
-- Related: MARS-828 Threshold Column Rename Compatibility
|
||||||
|
--=============================================================================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON
|
||||||
|
|
||||||
|
PROMPT ========================================================================
|
||||||
|
PROMPT Installing CT_MRDS.FILE_MANAGER Package Specification v3.3.2
|
||||||
|
PROMPT ========================================================================
|
||||||
|
|
||||||
|
@@new_version/FILE_MANAGER.pkg
|
||||||
|
|
||||||
|
-- Verify package compilation (check specific schema when installing as ADMIN)
|
||||||
|
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
|
||||||
|
FROM ALL_OBJECTS
|
||||||
|
WHERE OWNER = 'CT_MRDS'
|
||||||
|
AND OBJECT_NAME = 'FILE_MANAGER'
|
||||||
|
AND OBJECT_TYPE = 'PACKAGE';
|
||||||
|
|
||||||
|
PROMPT SUCCESS: FILE_MANAGER Package Specification v3.3.2 installed
|
||||||
|
|
||||||
|
--=============================================================================================================================
|
||||||
|
-- End of Script
|
||||||
|
--=============================================================================================================================
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
--=============================================================================================================================
|
||||||
|
-- MARS-828: Install CT_MRDS.FILE_MANAGER Package Body v3.3.2
|
||||||
|
--=============================================================================================================================
|
||||||
|
-- Purpose: Deploy FILE_MANAGER Package Body with MARS-828 threshold column compatibility
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-20
|
||||||
|
-- Related: MARS-828 Threshold Column Rename Compatibility
|
||||||
|
--=============================================================================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON
|
||||||
|
|
||||||
|
PROMPT ========================================================================
|
||||||
|
PROMPT Installing CT_MRDS.FILE_MANAGER Package Body v3.3.2
|
||||||
|
PROMPT ========================================================================
|
||||||
|
|
||||||
|
@@new_version/FILE_MANAGER.pkb
|
||||||
|
|
||||||
|
-- Verify package compilation (check specific schema when installing as ADMIN)
|
||||||
|
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
|
||||||
|
FROM ALL_OBJECTS
|
||||||
|
WHERE OWNER = 'CT_MRDS'
|
||||||
|
AND OBJECT_NAME = 'FILE_MANAGER'
|
||||||
|
AND OBJECT_TYPE IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
|
ORDER BY OBJECT_TYPE;
|
||||||
|
|
||||||
|
-- Check for any compilation errors
|
||||||
|
SELECT 'COMPILATION ERRORS FOUND' AS WARNING
|
||||||
|
FROM ALL_ERRORS
|
||||||
|
WHERE OWNER = 'CT_MRDS'
|
||||||
|
AND NAME = 'FILE_MANAGER'
|
||||||
|
AND TYPE = 'PACKAGE BODY'
|
||||||
|
AND ROWNUM = 1;
|
||||||
|
|
||||||
|
PROMPT SUCCESS: FILE_MANAGER Package Body v3.3.2 installed
|
||||||
|
|
||||||
|
--=============================================================================================================================
|
||||||
|
-- End of Script
|
||||||
|
--=============================================================================================================================
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
-- MARS-828 ROLLBACK: Remove TRASH retention statuses from A_SOURCE_FILE_RECEIVED
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-09
|
||||||
|
-- Description: Rollback TRASH retention statuses to original constraint
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT MARS-828 ROLLBACK: Removing TRASH retention statuses
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
-- Check if any files have new statuses
|
||||||
|
DECLARE
|
||||||
|
vTrashCount NUMBER;
|
||||||
|
vPurgedCount NUMBER;
|
||||||
|
BEGIN
|
||||||
|
SELECT COUNT(*) INTO vTrashCount
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
|
||||||
|
SELECT COUNT(*) INTO vPurgedCount
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE PROCESSING_STATUS = 'ARCHIVED_AND_PURGED';
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Files with ARCHIVED_AND_TRASHED status: ' || vTrashCount);
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Files with ARCHIVED_AND_PURGED status: ' || vPurgedCount);
|
||||||
|
|
||||||
|
IF vTrashCount > 0 OR vPurgedCount > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('WARNING: Files exist with new statuses!');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Migrating statuses to ARCHIVED before rollback...');
|
||||||
|
|
||||||
|
-- Migrate new statuses back to ARCHIVED
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
SET PROCESSING_STATUS = 'ARCHIVED'
|
||||||
|
WHERE PROCESSING_STATUS IN ('ARCHIVED_AND_TRASHED', 'ARCHIVED_AND_PURGED');
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Migrated ' || SQL%ROWCOUNT || ' records to ARCHIVED status');
|
||||||
|
ELSE
|
||||||
|
DBMS_OUTPUT.PUT_LINE('No files with new statuses - safe to rollback');
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
-- Drop new constraint
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED DROP CONSTRAINT A_SOURCE_FILE_RECEIVED_CHK;
|
||||||
|
|
||||||
|
-- Restore original constraint
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED ADD CONSTRAINT A_SOURCE_FILE_RECEIVED_CHK
|
||||||
|
CHECK (PROCESSING_STATUS IN (
|
||||||
|
'RECEIVED',
|
||||||
|
'VALIDATED',
|
||||||
|
'VALIDATION_FAILED',
|
||||||
|
'READY_FOR_INGESTION',
|
||||||
|
'INGESTED',
|
||||||
|
'ARCHIVED'
|
||||||
|
));
|
||||||
|
|
||||||
|
-- Remove comment
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PROCESSING_STATUS IS
|
||||||
|
'File processing status: RECEIVED → VALIDATED → READY_FOR_INGESTION → INGESTED → ARCHIVED';
|
||||||
|
|
||||||
|
-- Verify constraint restored
|
||||||
|
SELECT constraint_name, constraint_type, search_condition
|
||||||
|
FROM user_constraints
|
||||||
|
WHERE table_name = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND constraint_name = 'A_SOURCE_FILE_RECEIVED_CHK';
|
||||||
|
|
||||||
|
-- Show current status distribution
|
||||||
|
SELECT PROCESSING_STATUS, COUNT(*) as FILE_COUNT
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
GROUP BY PROCESSING_STATUS
|
||||||
|
ORDER BY PROCESSING_STATUS;
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT TRASH retention statuses rollback completed
|
||||||
|
PROMPT Original constraint restored
|
||||||
|
PROMPT All ARCHIVED_AND_TRASHED/ARCHIVED_AND_PURGED migrated to ARCHIVED
|
||||||
|
PROMPT ========================================
|
||||||
@@ -1,30 +1,41 @@
|
|||||||
-- MARS-828: Rollback archival strategy columns
|
-- MARS-828: Rollback archival strategy columns
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2026-01-27
|
-- Date: 2026-01-27
|
||||||
-- Description: Remove ARCHIVAL_STRATEGY and MINIMUM_AGE_MONTHS columns
|
-- Description: Remove ARCHIVAL_STRATEGY, MINIMUM_AGE_MONTHS, IS_ARCHIVE_ENABLED, and IS_KEEP_IN_TRASH columns
|
||||||
|
|
||||||
PROMPT ========================================
|
PROMPT ========================================
|
||||||
PROMPT MARS-828: Removing archival strategy columns
|
PROMPT MARS-828: Removing archival strategy and config columns
|
||||||
PROMPT ========================================
|
PROMPT ========================================
|
||||||
|
|
||||||
-- Drop check constraint first
|
-- Drop check constraints first
|
||||||
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
DROP CONSTRAINT CHK_ARCHIVAL_STRATEGY;
|
DROP CONSTRAINT CHK_ARCHIVAL_STRATEGY;
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
DROP CONSTRAINT CHK_IS_ARCHIVE_ENABLED;
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
DROP CONSTRAINT CHK_IS_KEEP_IN_TRASH;
|
||||||
|
|
||||||
-- Drop columns
|
-- Drop columns
|
||||||
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG DROP (
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG DROP (
|
||||||
ARCHIVAL_STRATEGY,
|
ARCHIVAL_STRATEGY,
|
||||||
MINIMUM_AGE_MONTHS
|
MINIMUM_AGE_MONTHS
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG DROP (
|
||||||
|
IS_ARCHIVE_ENABLED,
|
||||||
|
IS_KEEP_IN_TRASH
|
||||||
|
);
|
||||||
|
|
||||||
-- Verify columns dropped
|
-- Verify columns dropped
|
||||||
SELECT
|
SELECT
|
||||||
column_name
|
column_name
|
||||||
FROM all_tab_columns
|
FROM all_tab_columns
|
||||||
WHERE owner = 'CT_MRDS'
|
WHERE owner = 'CT_MRDS'
|
||||||
AND table_name = 'A_SOURCE_FILE_CONFIG'
|
AND table_name = 'A_SOURCE_FILE_CONFIG'
|
||||||
AND column_name IN ('ARCHIVAL_STRATEGY', 'MINIMUM_AGE_MONTHS');
|
AND column_name IN ('ARCHIVAL_STRATEGY', 'MINIMUM_AGE_MONTHS', 'IS_ARCHIVE_ENABLED', 'IS_KEEP_IN_TRASH');
|
||||||
|
|
||||||
PROMPT ========================================
|
PROMPT ========================================
|
||||||
PROMPT Archival strategy columns removed successfully
|
PROMPT Archival strategy and config columns removed successfully
|
||||||
PROMPT ========================================
|
PROMPT ========================================
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
-- MARS-828: Rollback threshold column renames
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-01-28
|
||||||
|
-- Description: Reverts threshold columns back to original naming
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT MARS-828: Rolling back threshold column renames
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
-- Revert threshold columns to original names
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
RENAME COLUMN ARCHIVE_THRESHOLD_DAYS TO DAYS_FOR_ARCHIVE_THRESHOLD;
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
RENAME COLUMN ARCHIVE_THRESHOLD_FILES_COUNT TO FILES_COUNT_OVER_ARCHIVE_THRESHOLD;
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
RENAME COLUMN ARCHIVE_THRESHOLD_BYTES_SUM TO BYTES_SUM_OVER_ARCHIVE_THRESHOLD;
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
RENAME COLUMN ARCHIVE_THRESHOLD_ROWS_COUNT TO ROWS_COUNT_OVER_ARCHIVE_THRESHOLD;
|
||||||
|
|
||||||
|
-- Verify rollback
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT Verifying threshold column rollback...
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
column_name,
|
||||||
|
data_type,
|
||||||
|
data_length
|
||||||
|
FROM all_tab_columns
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name = 'A_SOURCE_FILE_CONFIG'
|
||||||
|
AND (column_name LIKE '%ARCHIVE_THRESHOLD%' OR column_name LIKE 'DAYS_FOR%')
|
||||||
|
ORDER BY column_id;
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT Expected original columns:
|
||||||
|
PROMPT DAYS_FOR_ARCHIVE_THRESHOLD
|
||||||
|
PROMPT FILES_COUNT_OVER_ARCHIVE_THRESHOLD
|
||||||
|
PROMPT BYTES_SUM_OVER_ARCHIVE_THRESHOLD
|
||||||
|
PROMPT ROWS_COUNT_OVER_ARCHIVE_THRESHOLD
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
PROMPT Threshold column renames rolled back successfully
|
||||||
|
PROMPT ========================================
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
-- =====================================================================
|
||||||
|
-- Script: 94b_MARS_828_rollback_column_comments.sql
|
||||||
|
-- MARS Issue: MARS-828
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-20
|
||||||
|
-- Purpose: Remove column comments added by 01b_MARS_828_add_column_comments.sql
|
||||||
|
-- Description: Optional rollback - removes documentation but does not affect functionality
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT MARS-828: Removing column comments (optional)
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- Remove A_SOURCE_FILE_CONFIG Column Comments
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT Removing column comments from A_SOURCE_FILE_CONFIG...
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_KEY IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_DESC IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_NAME_PATTERN IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.TEMPLATE_TABLE_NAME IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.CONTAINER_FILE_KEY IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_DAYS IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_FILES_COUNT IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_BYTES_SUM IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_ROWS_COUNT IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ODS_SCHEMA_NAME IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.HOURS_TO_EXPIRE_STATISTICS IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVAL_STRATEGY IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.MINIMUM_AGE_MONTHS IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.IS_ARCHIVE_ENABLED IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.IS_KEEP_IN_TRASH IS '';
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- Remove A_SOURCE_FILE_RECEIVED Column Comments
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT Removing column comments from A_SOURCE_FILE_RECEIVED...
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_CONFIG_KEY IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.SOURCE_FILE_NAME IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.CHECKSUM IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.CREATED IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.BYTES IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.RECEPTION_DATE IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PROCESSING_STATUS IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.EXTERNAL_TABLE_NAME IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PARTITION_YEAR IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PARTITION_MONTH IS '';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.ARCH_PATH IS '';
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- Verification
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Verifying column comments removed...
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
table_name,
|
||||||
|
COUNT(*) as total_columns,
|
||||||
|
COUNT(CASE WHEN comments IS NOT NULL AND LENGTH(comments) > 0 THEN 1 END) as documented_columns
|
||||||
|
FROM all_col_comments
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name IN ('A_SOURCE_FILE_CONFIG', 'A_SOURCE_FILE_RECEIVED')
|
||||||
|
GROUP BY table_name
|
||||||
|
ORDER BY table_name;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT Column comments removed successfully
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT NOTE: This is an optional rollback step
|
||||||
|
PROMPT Database functionality is not affected
|
||||||
|
PROMPT ========================================
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
-- MARS-828 ROLLBACK: Revoke EXECUTE privilege on T_FILENAME from MRDS_LOADER
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-17
|
||||||
|
-- Description: Revokes EXECUTE privilege on CT_MRDS.T_FILENAME type from MRDS_LOADER user
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT MARS-828: Revoking EXECUTE on T_FILENAME
|
||||||
|
PROMPT ========================================
|
||||||
|
|
||||||
|
-- Revoke EXECUTE privilege
|
||||||
|
REVOKE EXECUTE ON CT_MRDS.T_FILENAME FROM MRDS_LOADER;
|
||||||
|
|
||||||
|
PROMPT EXECUTE privilege on CT_MRDS.T_FILENAME revoked from MRDS_LOADER
|
||||||
|
|
||||||
|
-- Verify revocation
|
||||||
|
SELECT GRANTEE, PRIVILEGE, GRANTABLE
|
||||||
|
FROM USER_TAB_PRIVS
|
||||||
|
WHERE TABLE_NAME = 'T_FILENAME'
|
||||||
|
AND GRANTEE = 'MRDS_LOADER';
|
||||||
|
|
||||||
|
PROMPT ========================================
|
||||||
|
PROMPT T_FILENAME privilege revocation completed
|
||||||
|
PROMPT ========================================
|
||||||
@@ -0,0 +1,274 @@
|
|||||||
|
-- =====================================================================
|
||||||
|
-- Script: 96_MARS_828_rollback_release01_configuration.sql
|
||||||
|
-- MARS Issue: MARS-828
|
||||||
|
-- Purpose: ROLLBACK archival configuration for Release 01 tables
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-05
|
||||||
|
--
|
||||||
|
-- Description:
|
||||||
|
-- Rolls back archival configuration for 25 tables by setting all
|
||||||
|
-- archival parameters back to NULL (unconfigured state):
|
||||||
|
-- - ARCHIVAL_STRATEGY
|
||||||
|
-- - MINIMUM_AGE_MONTHS
|
||||||
|
-- - ARCHIVE_THRESHOLD_FILES_COUNT
|
||||||
|
-- - ARCHIVE_THRESHOLD_ROWS_COUNT
|
||||||
|
-- - ARCHIVE_THRESHOLD_BYTES_SUM
|
||||||
|
-- - HOURS_TO_EXPIRE_STATISTICS
|
||||||
|
--
|
||||||
|
-- This script reverts changes made by:
|
||||||
|
-- - 06_MARS_828_configure_release01_tables.sql
|
||||||
|
--
|
||||||
|
-- Dependencies:
|
||||||
|
-- - A_SOURCE_FILE_CONFIG table with archival columns
|
||||||
|
-- =====================================================================
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT MARS-828: ROLLBACK - Remove Archival Configuration
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT
|
||||||
|
PROMPT This script will REMOVE archival configuration from 25 tables
|
||||||
|
PROMPT
|
||||||
|
PROMPT WARNING: This will reset ALL archival parameters to NULL
|
||||||
|
PROMPT
|
||||||
|
PROMPT Tables affected:
|
||||||
|
PROMPT - 19 LM tables
|
||||||
|
PROMPT - 2 CSDB DEBT tables
|
||||||
|
PROMPT - 4 CSDB rating/description tables
|
||||||
|
PROMPT
|
||||||
|
PROMPT Current timestamp:
|
||||||
|
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS CURRENT_TIME FROM DUAL;
|
||||||
|
PROMPT
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT SECTION 1: Rollback LM Tables Configuration
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
-- Rollback all 19 LM tables in a single statement
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = NULL,
|
||||||
|
MINIMUM_AGE_MONTHS = NULL,
|
||||||
|
ODS_SCHEMA_NAME = NULL,
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT = NULL,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT = NULL,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM = NULL,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS = NULL
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND A_SOURCE_KEY = 'LM'
|
||||||
|
AND TABLE_ID IN (
|
||||||
|
'LM_STANDING_FACILITIES',
|
||||||
|
'LM_STANDING_FACILITIES_HEADER',
|
||||||
|
'LM_TTS_HEADER',
|
||||||
|
'LM_TTS_ITEM',
|
||||||
|
'LM_ADHOC_ADJUSTMENTS_HEADER',
|
||||||
|
'LM_ADHOC_ADJUSTMENTS_ITEM',
|
||||||
|
'LM_ADHOC_ADJUSTMENTS_ITEM_HEADER',
|
||||||
|
'LM_BALANCESHEET_HEADER',
|
||||||
|
'LM_BALANCESHEET_ITEM',
|
||||||
|
'LM_CSM_ADJUSTMENTS_HEADER',
|
||||||
|
'LM_CSM_ADJUSTMENTS_ITEM',
|
||||||
|
'LM_CSM_ADJUSTMENTS_ITEM_HEADER',
|
||||||
|
'LM_CURRENT_ACCOUNTS_HEADER',
|
||||||
|
'LM_CURRENT_ACCOUNTS_ITEM',
|
||||||
|
'LM_FORECAST_HEADER',
|
||||||
|
'LM_FORECAST_ITEM',
|
||||||
|
'LM_QRE_ADJUSTMENTS_HEADER',
|
||||||
|
'LM_QRE_ADJUSTMENTS_ITEM',
|
||||||
|
'LM_QRE_ADJUSTMENTS_ITEM_HEADER'
|
||||||
|
);
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT LM tables rollback completed
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT SECTION 2: Rollback CSDB DEBT Tables Configuration
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
-- Rollback CSDB DEBT tables
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = NULL,
|
||||||
|
MINIMUM_AGE_MONTHS = NULL,
|
||||||
|
ODS_SCHEMA_NAME = NULL,
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT = NULL,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT = NULL,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM = NULL,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS = NULL
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND A_SOURCE_KEY = 'CSDB'
|
||||||
|
AND TABLE_ID IN ('CSDB_DEBT', 'CSDB_DEBT_DAILY');
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB DEBT tables rollback completed
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT SECTION 3: Rollback CSDB Rating/Description Tables Configuration
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
-- Rollback CSDB rating/description tables
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = NULL,
|
||||||
|
MINIMUM_AGE_MONTHS = NULL,
|
||||||
|
ODS_SCHEMA_NAME = NULL,
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT = NULL,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT = NULL,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM = NULL,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS = NULL
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND A_SOURCE_KEY = 'CSDB'
|
||||||
|
AND TABLE_ID IN (
|
||||||
|
'CSDB_INSTR_RAT_FULL',
|
||||||
|
'CSDB_INSTR_DESC_FULL',
|
||||||
|
'CSDB_ISSUER_RAT_FULL',
|
||||||
|
'CSDB_ISSUER_DESC_FULL'
|
||||||
|
);
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB rating/description tables rollback completed
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Committing rollback changes...
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Rollback committed successfully.
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT VERIFICATION: Archival Configuration Removed
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT LM Tables (should all be NULL):
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT AS FILE_THR,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT AS ROW_THR,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY IS NULL
|
||||||
|
AND MINIMUM_AGE_MONTHS IS NULL
|
||||||
|
AND ARCHIVE_THRESHOLD_FILES_COUNT IS NULL
|
||||||
|
AND ARCHIVE_THRESHOLD_ROWS_COUNT IS NULL
|
||||||
|
AND ARCHIVE_THRESHOLD_BYTES_SUM IS NULL
|
||||||
|
AND HOURS_TO_EXPIRE_STATISTICS IS NULL
|
||||||
|
THEN 'OK'
|
||||||
|
ELSE 'ERROR - Still configured'
|
||||||
|
END AS STATUS
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE A_SOURCE_KEY = 'LM'
|
||||||
|
AND SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND TABLE_ID LIKE 'LM_%'
|
||||||
|
ORDER BY TABLE_ID;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB DEBT Tables (should all be NULL):
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT AS FILE_THR,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT AS ROW_THR,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY IS NULL
|
||||||
|
AND MINIMUM_AGE_MONTHS IS NULL
|
||||||
|
AND ARCHIVE_THRESHOLD_FILES_COUNT IS NULL
|
||||||
|
AND ARCHIVE_THRESHOLD_ROWS_COUNT IS NULL
|
||||||
|
AND ARCHIVE_THRESHOLD_BYTES_SUM IS NULL
|
||||||
|
AND HOURS_TO_EXPIRE_STATISTICS IS NULL
|
||||||
|
THEN 'OK'
|
||||||
|
ELSE 'ERROR - Still configured'
|
||||||
|
END AS STATUS
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE A_SOURCE_KEY = 'CSDB'
|
||||||
|
AND SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND TABLE_ID IN ('CSDB_DEBT', 'CSDB_DEBT_DAILY')
|
||||||
|
ORDER BY TABLE_ID;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT CSDB Rating/Description Tables (should all be NULL):
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT AS FILE_THR,
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT AS ROW_THR,
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY IS NULL
|
||||||
|
AND MINIMUM_AGE_MONTHS IS NULL
|
||||||
|
AND ARCHIVE_THRESHOLD_FILES_COUNT IS NULL
|
||||||
|
AND ARCHIVE_THRESHOLD_ROWS_COUNT IS NULL
|
||||||
|
AND ARCHIVE_THRESHOLD_BYTES_SUM IS NULL
|
||||||
|
AND HOURS_TO_EXPIRE_STATISTICS IS NULL
|
||||||
|
THEN 'OK'
|
||||||
|
ELSE 'ERROR - Still configured'
|
||||||
|
END AS STATUS
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE A_SOURCE_KEY = 'CSDB'
|
||||||
|
AND SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND TABLE_ID IN ('CSDB_INSTR_RAT_FULL', 'CSDB_INSTR_DESC_FULL', 'CSDB_ISSUER_RAT_FULL', 'CSDB_ISSUER_DESC_FULL')
|
||||||
|
ORDER BY TABLE_ID;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Summary: Total Tables with Rollback Applied
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
COUNT(*) AS TOTAL_TABLES,
|
||||||
|
SUM(CASE WHEN ARCHIVAL_STRATEGY IS NULL THEN 1 ELSE 0 END) AS STRATEGY_NULL,
|
||||||
|
SUM(CASE WHEN MINIMUM_AGE_MONTHS IS NULL THEN 1 ELSE 0 END) AS MIN_AGE_NULL,
|
||||||
|
SUM(CASE WHEN FILES_COUNT_OVER_ARCHIVE_THRESHOLD IS NULL THEN 1 ELSE 0 END) AS FILE_THR_NULL,
|
||||||
|
SUM(CASE WHEN ROWS_COUNT_OVER_ARCHIVE_THRESHOLD IS NULL THEN 1 ELSE 0 END) AS ROWS_THR_NULL,
|
||||||
|
SUM(CASE WHEN BYTES_SUM_OVER_ARCHIVE_THRESHOLD IS NULL THEN 1 ELSE 0 END) AS BYTES_THR_NULL,
|
||||||
|
SUM(CASE WHEN HOURS_TO_EXPIRE_STATISTICS IS NULL THEN 1 ELSE 0 END) AS STATS_NULL
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND ((A_SOURCE_KEY = 'LM' AND TABLE_ID LIKE 'LM_%')
|
||||||
|
OR (A_SOURCE_KEY = 'CSDB' AND TABLE_ID IN (
|
||||||
|
'CSDB_DEBT', 'CSDB_DEBT_DAILY',
|
||||||
|
'CSDB_INSTR_RAT_FULL', 'CSDB_INSTR_DESC_FULL',
|
||||||
|
'CSDB_ISSUER_RAT_FULL', 'CSDB_ISSUER_DESC_FULL'
|
||||||
|
)));
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Expected: All counts should be 25 (all parameters NULL for all tables)
|
||||||
|
PROMPT - TOTAL_TABLES = 25
|
||||||
|
PROMPT - STRATEGY_NULL = 25
|
||||||
|
PROMPT - MIN_AGE_NULL = 25
|
||||||
|
PROMPT - FILE_THR_NULL = 25
|
||||||
|
PROMPT - ROWS_THR_NULL = 25
|
||||||
|
PROMPT - BYTES_THR_NULL = 25
|
||||||
|
PROMPT - STATS_NULL = 25
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Rollback Complete
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT
|
||||||
|
PROMPT Next Steps:
|
||||||
|
PROMPT 1. Review verification results above
|
||||||
|
PROMPT 2. All 25 tables should show STATUS = 'OK'
|
||||||
|
PROMPT 3. All archival parameters should be NULL
|
||||||
|
PROMPT 4. Tables are now in unconfigured state (no archival strategy)
|
||||||
|
PROMPT
|
||||||
|
PROMPT To restore configuration, re-run:
|
||||||
|
PROMPT @06_MARS_828_configure_release01_tables.sql
|
||||||
|
PROMPT
|
||||||
|
PROMPT Log file: 96_MARS_828_rollback_release01_configuration.log
|
||||||
|
PROMPT =====================================================================
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
-- ===================================================================
|
||||||
|
-- MARS-828: Rollback FILE_MANAGER Package Specification to v3.3.1
|
||||||
|
-- ===================================================================
|
||||||
|
-- Purpose: Restore previous package specification version (pre-threshold column rename compatibility)
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-20
|
||||||
|
-- WARNING: This removes MARS-828 threshold column compatibility from FILE_MANAGER
|
||||||
|
-- ===================================================================
|
||||||
|
|
||||||
|
@@rollback_version/FILE_MANAGER.pkg
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
-- ===================================================================
|
||||||
|
-- MARS-828: Rollback FILE_MANAGER Package Body to v3.3.1
|
||||||
|
-- ===================================================================
|
||||||
|
-- Purpose: Restore previous package body version (pre-threshold column rename compatibility)
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-20
|
||||||
|
-- WARNING: This removes MARS-828 threshold column compatibility from FILE_MANAGER
|
||||||
|
-- ===================================================================
|
||||||
|
|
||||||
|
@@rollback_version/FILE_MANAGER.pkb
|
||||||
@@ -1,269 +0,0 @@
|
|||||||
# MARS-828: Enhanced Archival Strategies
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Implementation of flexible archival strategies for FILE_ARCHIVER package to support business requirements for different data retention policies across source systems.
|
|
||||||
|
|
||||||
### Background
|
|
||||||
|
|
||||||
**Issue**: Current FILE_ARCHIVER v2.0.0 uses fixed threshold-based archival (DAYS_FOR_ARCHIVE_THRESHOLD) which cannot accommodate:
|
|
||||||
1. **LM/TOP sources**: Archive all data except current month
|
|
||||||
2. **CSDB sources**: Archive only data older than 6 months
|
|
||||||
|
|
||||||
**Root Cause**: Hardcoded WHERE clause in ARCHIVE_TABLE_DATA procedure:
|
|
||||||
```sql
|
|
||||||
WHERE extract(day from (systimestamp - workflow_start)) > DAYS_FOR_ARCHIVE_THRESHOLD
|
|
||||||
```
|
|
||||||
|
|
||||||
**Solution**: Introduce ARCHIVAL_STRATEGY configuration column with four strategies:
|
|
||||||
- `THRESHOLD_BASED` - Days-based threshold (backward compatible)
|
|
||||||
- `CURRENT_MONTH_ONLY` - Keep only current month data
|
|
||||||
- `MINIMUM_AGE_MONTHS` - Archive data older than X months
|
|
||||||
- `HYBRID` - Combination of current month and minimum age
|
|
||||||
|
|
||||||
## Changes Made
|
|
||||||
|
|
||||||
### Database Schema Changes
|
|
||||||
**Table**: CT_MRDS.A_SOURCE_FILE_CONFIG
|
|
||||||
|
|
||||||
**Before**:
|
|
||||||
```sql
|
|
||||||
-- Only threshold-based configuration available
|
|
||||||
DAYS_FOR_ARCHIVE_THRESHOLD NUMBER DEFAULT 30
|
|
||||||
```
|
|
||||||
|
|
||||||
**After**:
|
|
||||||
```sql
|
|
||||||
-- Flexible strategy-based configuration
|
|
||||||
ARCHIVAL_STRATEGY VARCHAR2(30) DEFAULT 'THRESHOLD_BASED' NOT NULL,
|
|
||||||
MINIMUM_AGE_MONTHS NUMBER(3),
|
|
||||||
DAYS_FOR_ARCHIVE_THRESHOLD NUMBER DEFAULT 30,
|
|
||||||
CONSTRAINT CHK_ARCHIVAL_STRATEGY CHECK (ARCHIVAL_STRATEGY IN ('THRESHOLD_BASED', 'CURRENT_MONTH_ONLY', 'MINIMUM_AGE_MONTHS', 'HYBRID'))
|
|
||||||
```
|
|
||||||
|
|
||||||
**New Trigger**: TRG_BI_ARCHIVAL_STRATEGY_VAL
|
|
||||||
- Validates MINIMUM_AGE_MONTHS required for strategies that need it
|
|
||||||
- Ensures data integrity before insert/update
|
|
||||||
|
|
||||||
### Package Changes
|
|
||||||
**Package**: CT_MRDS.FILE_ARCHIVER
|
|
||||||
|
|
||||||
**Version**: 2.0.0 → 3.0.0 (MAJOR - breaking changes to internal logic)
|
|
||||||
|
|
||||||
**Specification Changes**:
|
|
||||||
- Updated PACKAGE_VERSION: '2.0.0' → '3.0.0'
|
|
||||||
- Updated VERSION_HISTORY with MARS-828 entry
|
|
||||||
- Updated PACKAGE_BUILD_DATE to deployment date
|
|
||||||
|
|
||||||
**Body Changes**:
|
|
||||||
1. **New Function**: GET_ARCHIVAL_WHERE_CLAUSE(pSourceFileConfig) - Returns strategy-specific WHERE clause
|
|
||||||
2. **Updated**: ARCHIVE_TABLE_DATA - Uses GET_ARCHIVAL_WHERE_CLAUSE for flexible filtering
|
|
||||||
3. **Updated**: GATHER_TABLE_STAT - Uses GET_ARCHIVAL_WHERE_CLAUSE for statistics calculation
|
|
||||||
|
|
||||||
**File Structure**:
|
|
||||||
- **rollback/** - Backup of FILE_ARCHIVER v2.0.0 (for rollback)
|
|
||||||
- **new_version/** - Updated FILE_ARCHIVER v3.0.0 (with strategy support)
|
|
||||||
|
|
||||||
## Archival Strategies
|
|
||||||
|
|
||||||
| Strategy | WHERE Clause Logic | Configuration Required | Use Case |
|
|
||||||
|----------|-------------------|----------------------|----------|
|
|
||||||
| `THRESHOLD_BASED` | `extract(day from (systimestamp - workflow_start)) > DAYS_FOR_ARCHIVE_THRESHOLD` | DAYS_FOR_ARCHIVE_THRESHOLD | Legacy compatibility |
|
|
||||||
| `CURRENT_MONTH_ONLY` | `TRUNC(workflow_start, 'MM') < TRUNC(SYSDATE, 'MM')` | None | General sources (LM, TOP) |
|
|
||||||
| `MINIMUM_AGE_MONTHS` | `workflow_start < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -X)` | MINIMUM_AGE_MONTHS | CSDB (6 months retention) |
|
|
||||||
| `HYBRID` | Both CURRENT_MONTH_ONLY AND MINIMUM_AGE_MONTHS | MINIMUM_AGE_MONTHS | Advanced scenarios |
|
|
||||||
|
|
||||||
## Configuration Examples
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- LM/TOP sources: Archive everything except current month
|
|
||||||
UPDATE A_SOURCE_FILE_CONFIG
|
|
||||||
SET ARCHIVAL_STRATEGY = 'CURRENT_MONTH_ONLY',
|
|
||||||
MINIMUM_AGE_MONTHS = NULL
|
|
||||||
WHERE A_SOURCE_KEY IN ('LM', 'TOP');
|
|
||||||
|
|
||||||
-- CSDB: Archive only data older than 6 months
|
|
||||||
UPDATE A_SOURCE_FILE_CONFIG
|
|
||||||
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
|
||||||
MINIMUM_AGE_MONTHS = 6
|
|
||||||
WHERE A_SOURCE_KEY = 'CSDB'
|
|
||||||
AND TABLE_ID IN ('DEBT', 'DEBT_DAILY');
|
|
||||||
|
|
||||||
-- Legacy sources: Keep existing threshold behavior
|
|
||||||
UPDATE A_SOURCE_FILE_CONFIG
|
|
||||||
SET ARCHIVAL_STRATEGY = 'THRESHOLD_BASED',
|
|
||||||
DAYS_FOR_ARCHIVE_THRESHOLD = 30
|
|
||||||
WHERE A_SOURCE_KEY = 'C2D';
|
|
||||||
|
|
||||||
-- Advanced hybrid: Current month + 3 months minimum
|
|
||||||
UPDATE A_SOURCE_FILE_CONFIG
|
|
||||||
SET ARCHIVAL_STRATEGY = 'HYBRID',
|
|
||||||
MINIMUM_AGE_MONTHS = 3
|
|
||||||
WHERE A_SOURCE_KEY = 'SPECIAL';
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deployment
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
- **User**: ADMIN with full privileges
|
|
||||||
- **Database**: Oracle 23ai
|
|
||||||
- **ENV_MANAGER**: v3.x or higher
|
|
||||||
- **FILE_MANAGER**: v3.x or higher
|
|
||||||
- **FILE_ARCHIVER**: v2.0.0 (will upgrade to v3.0.0)
|
|
||||||
- **Table**: A_SOURCE_FILE_CONFIG must exist
|
|
||||||
|
|
||||||
### Installation Steps
|
|
||||||
|
|
||||||
**Option 1: Master Script (Recommended)**
|
|
||||||
```powershell
|
|
||||||
# Navigate to MARS-828 directory
|
|
||||||
cd .\MARS_Packages\REL01_ADDITIONS\MARS-828
|
|
||||||
|
|
||||||
# Execute installation (requires ADMIN user)
|
|
||||||
sql "ADMIN/Cloudpass#34@ggmichalski_high" "@install_mars828.sql"
|
|
||||||
|
|
||||||
# Log file created: log/INSTALL_MARS_828_<PDB>_<timestamp>.log
|
|
||||||
```
|
|
||||||
|
|
||||||
**Installation Workflow**:
|
|
||||||
1. **Add Columns** - ARCHIVAL_STRATEGY, MINIMUM_AGE_MONTHS to A_SOURCE_FILE_CONFIG
|
|
||||||
2. **Create Trigger** - Validation trigger TRG_BI_ARCHIVAL_STRATEGY_VAL
|
|
||||||
3. **Deploy Package Spec** - FILE_ARCHIVER v3.0.0 specification
|
|
||||||
4. **Deploy Package Body** - FILE_ARCHIVER v3.0.0 body with GET_ARCHIVAL_WHERE_CLAUSE
|
|
||||||
5. **Verify Installation** - Check package compilation and structure
|
|
||||||
6. **Track Version** - Record v3.0.0 in ENV_MANAGER
|
|
||||||
7. **Verify Packages** - Check for untracked changes using ENV_MANAGER hash verification
|
|
||||||
|
|
||||||
**Option 2: Using Get-Content**
|
|
||||||
```powershell
|
|
||||||
Get-Content "MARS_Packages\REL01_ADDITIONS\MARS-828\install_mars828.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verification
|
|
||||||
```sql
|
|
||||||
-- Check package compilation status
|
|
||||||
SELECT object_name, object_type, status
|
|
||||||
FROM all_objects
|
|
||||||
WHERE owner = 'CT_MRDS'
|
|
||||||
AND object_name = 'FILE_ARCHIVER'
|
|
||||||
AND object_type IN ('PACKAGE', 'PACKAGE BODY');
|
|
||||||
|
|
||||||
-- Verify package version
|
|
||||||
SELECT CT_MRDS.FILE_ARCHIVER.GET_VERSION() FROM DUAL;
|
|
||||||
-- Expected: 3.0.0
|
|
||||||
|
|
||||||
-- Check new columns exist
|
|
||||||
SELECT column_name, data_type, data_default
|
|
||||||
FROM all_tab_columns
|
|
||||||
WHERE owner = 'CT_MRDS'
|
|
||||||
AND table_name = 'A_SOURCE_FILE_CONFIG'
|
|
||||||
AND column_name IN ('ARCHIVAL_STRATEGY', 'MINIMUM_AGE_MONTHS');
|
|
||||||
|
|
||||||
-- Test strategy configuration
|
|
||||||
SELECT A_SOURCE_KEY, TABLE_ID, ARCHIVAL_STRATEGY, MINIMUM_AGE_MONTHS
|
|
||||||
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
|
||||||
ORDER BY A_SOURCE_KEY, TABLE_ID;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rollback
|
|
||||||
```powershell
|
|
||||||
# Execute rollback script (requires ADMIN user)
|
|
||||||
cd .\MARS_Packages\REL01_ADDITIONS\MARS-828
|
|
||||||
sql "ADMIN/Cloudpass#34@ggmichalski_high" "@rollback_mars828.sql"
|
|
||||||
|
|
||||||
# Log file created: log/ROLLBACK_MARS_828_<PDB>_<timestamp>.log
|
|
||||||
```
|
|
||||||
|
|
||||||
**Rollback Workflow**:
|
|
||||||
1. **Restore Package Body** - FILE_ARCHIVER v2.0.0 body
|
|
||||||
2. **Restore Package Spec** - FILE_ARCHIVER v2.0.0 specification
|
|
||||||
3. **Drop Trigger** - Remove TRG_BI_ARCHIVAL_STRATEGY_VAL
|
|
||||||
4. **Drop Columns** - Remove ARCHIVAL_STRATEGY, MINIMUM_AGE_MONTHS
|
|
||||||
5. **Track Rollback** - Record v2.0.0 restoration in ENV_MANAGER
|
|
||||||
6. **Verify Packages** - Check package hash consistency
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
**Test Scripts**: Located in `test/` folder
|
|
||||||
|
|
||||||
**Main Test Script**: test/test_archival_strategies.sql
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Test 1: CURRENT_MONTH_ONLY strategy
|
|
||||||
-- Expected: Archives data from previous months only
|
|
||||||
SELECT COUNT(*) FROM table WHERE TRUNC(workflow_start, 'MM') < TRUNC(SYSDATE, 'MM');
|
|
||||||
|
|
||||||
-- Test 2: MINIMUM_AGE_MONTHS strategy (6 months)
|
|
||||||
-- Expected: Archives data older than 6 months
|
|
||||||
SELECT COUNT(*) FROM table WHERE workflow_start < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -6);
|
|
||||||
|
|
||||||
-- Test 3: HYBRID strategy
|
|
||||||
-- Expected: Archives data from previous months AND older than X months
|
|
||||||
```
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
### Required Packages
|
|
||||||
- **CT_MRDS.ENV_MANAGER** v3.x - Error handling, logging, version tracking
|
|
||||||
- **CT_MRDS.FILE_MANAGER** v3.x - Bucket URI resolution
|
|
||||||
- **MRDS_LOADER.cloud_wrapper** - DBMS_CLOUD operations
|
|
||||||
|
|
||||||
### Database Objects
|
|
||||||
- **Table**: CT_MRDS.A_SOURCE_FILE_CONFIG - Configuration storage
|
|
||||||
- **Table**: CT_ODS.A_LOAD_HISTORY - Workflow tracking
|
|
||||||
- **Credential**: DEF_CRED_ARN - OCI bucket access
|
|
||||||
|
|
||||||
## Files Included
|
|
||||||
|
|
||||||
1. **README.md** - This documentation file
|
|
||||||
2. **.gitignore** - Git exclusions (confluence/, log/, test/, mock_data/)
|
|
||||||
3. **install_mars828.sql** - Master installation script with SPOOL logging (7 steps)
|
|
||||||
4. **rollback_mars828.sql** - Master rollback script (6 steps)
|
|
||||||
5. **01_MARS_828_install_add_archival_strategy_columns.sql** - ALTER TABLE DDL
|
|
||||||
6. **02_MARS_828_install_archival_strategy_trigger.sql** - CREATE TRIGGER DDL
|
|
||||||
7. **03_MARS_828_install_CT_MRDS_FILE_ARCHIVER_SPEC.sql** - Deploy package specification v3.0.0
|
|
||||||
8. **04_MARS_828_install_CT_MRDS_FILE_ARCHIVER_BODY.sql** - Deploy package body v3.0.0
|
|
||||||
9. **05_MARS_828_verify_installation.sql** - Verification queries
|
|
||||||
10. **91_MARS_828_rollback_FILE_ARCHIVER_SPEC.sql** - Restore package specification v2.0.0
|
|
||||||
11. **92_MARS_828_rollback_FILE_ARCHIVER_BODY.sql** - Restore package body v2.0.0
|
|
||||||
12. **93_MARS_828_rollback_trigger.sql** - DROP TRIGGER
|
|
||||||
13. **94_MARS_828_rollback_columns.sql** - ALTER TABLE DROP COLUMN
|
|
||||||
14. **track_package_versions.sql** - Universal version tracking script (Standard)
|
|
||||||
15. **verify_packages_version.sql** - Universal package verification script (Standard)
|
|
||||||
16. **test/** - Test scripts and validation scenarios
|
|
||||||
17. **rollback/** - Backup of FILE_ARCHIVER v2.0.0 (for rollback)
|
|
||||||
18. **new_version/** - Updated FILE_ARCHIVER v3.0.0 (deployment source)
|
|
||||||
|
|
||||||
## Impact Analysis
|
|
||||||
|
|
||||||
### Backward Compatibility
|
|
||||||
✅ **FULLY BACKWARD COMPATIBLE**: Default ARCHIVAL_STRATEGY = 'THRESHOLD_BASED' maintains existing behavior for all sources without configuration changes.
|
|
||||||
|
|
||||||
### Affected Procedures
|
|
||||||
1. **ARCHIVE_TABLE_DATA** - Uses GET_ARCHIVAL_WHERE_CLAUSE for WHERE clause generation
|
|
||||||
2. **GATHER_TABLE_STAT** - Uses GET_ARCHIVAL_WHERE_CLAUSE for statistics calculation
|
|
||||||
|
|
||||||
### Configuration Migration
|
|
||||||
No automatic migration required. New columns have sensible defaults:
|
|
||||||
- ARCHIVAL_STRATEGY = 'THRESHOLD_BASED' (maintains current behavior)
|
|
||||||
- MINIMUM_AGE_MONTHS = NULL (not required for THRESHOLD_BASED)
|
|
||||||
|
|
||||||
## Version History
|
|
||||||
- **v3.0.0** (2026-01-27): Added flexible archival strategies (CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID) via ARCHIVAL_STRATEGY configuration
|
|
||||||
- **v2.0.0** (2025-10-01): Initial FILE_ARCHIVER package with threshold-based archival
|
|
||||||
|
|
||||||
## Related JIRA Issues
|
|
||||||
- **MARS-828**: Enhanced Archival Strategies implementation
|
|
||||||
|
|
||||||
## Author
|
|
||||||
Created by: Grzegorz Michalski
|
|
||||||
Date: 2026-01-27
|
|
||||||
Schema: CT_MRDS
|
|
||||||
Package: FILE_ARCHIVER
|
|
||||||
|
|
||||||
|
|
||||||
Grzegorz Michalski
|
|
||||||
|
|
||||||
## Date
|
|
||||||
|
|
||||||
2026-01-27
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- MARS-828 Master Installation Script
|
-- MARS-828 Master Installation Script
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
-- Purpose: Deploy enhanced archival strategies for FILE_ARCHIVER package
|
-- Purpose: Deploy enhanced archival strategies for FILE_ARCHIVER package
|
||||||
-- Target Schema: CT_MRDS
|
-- Target Schema: CT_MRDS
|
||||||
-- Estimated Time: 2-3 minutes
|
-- Estimated Time: 2-3 minutes
|
||||||
@@ -34,10 +35,10 @@ PROMPT
|
|||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
PROMPT MARS-828 Installation Starting
|
PROMPT MARS-828 Installation Starting
|
||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
PROMPT Package: CT_MRDS.FILE_ARCHIVER
|
PROMPT Package: CT_MRDS.FILE_ARCHIVER v3.3.0 + CT_MRDS.FILE_MANAGER v3.3.2
|
||||||
PROMPT Change: Enhanced archival strategies (CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID)
|
PROMPT Change: Enhanced archival strategies (MINIMUM_AGE_MONTHS, HYBRID) + TRASH retention + Selective archiving + FILE_MANAGER compatibility
|
||||||
PROMPT Purpose: Flexible archival policies per data source
|
PROMPT Purpose: Flexible archival policies per data source with file retention and config-based control
|
||||||
PROMPT Steps: 7 (DDL, Trigger, Packages, Verify, Track, Verify)
|
PROMPT Steps: 14 (DDL, Rename, Comments, Trigger, Statuses, Grants, Packages, Verify, Track, Configure)
|
||||||
PROMPT Timestamp:
|
PROMPT Timestamp:
|
||||||
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS install_start FROM DUAL;
|
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS install_start FROM DUAL;
|
||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
@@ -54,40 +55,76 @@ END;
|
|||||||
WHENEVER SQLERROR CONTINUE
|
WHENEVER SQLERROR CONTINUE
|
||||||
|
|
||||||
-- Installation steps
|
-- Installation steps
|
||||||
PROMPT7: Adding archival strategy columns to A_SOURCE_FILE_CONFIG
|
PROMPT
|
||||||
PROMPT ===================================================================
|
PROMPT Step 1/12: Adding archival strategy and config columns to A_SOURCE_FILE_CONFIG
|
||||||
|
PROMPT ==============================================================================
|
||||||
@@01_MARS_828_install_add_archival_strategy_columns.sql
|
@@01_MARS_828_install_add_archival_strategy_columns.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 2/7: Creating validation trigger
|
PROMPT Step 2/12: Renaming threshold columns for consistent naming
|
||||||
|
PROMPT ==========================================================
|
||||||
|
@@01a_MARS_828_rename_threshold_columns.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 3/12: Adding comprehensive column comments
|
||||||
|
PROMPT ===============================================
|
||||||
|
@@01b_MARS_828_add_column_comments.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 4/12: Creating validation trigger
|
||||||
PROMPT ======================================
|
PROMPT ======================================
|
||||||
@@02_MARS_828_install_archival_strategy_trigger.sql
|
@@02_MARS_828_install_archival_strategy_trigger.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 3/7: Deploying FILE_ARCHIVER Package Specification v3.0.0
|
PROMPT Step 5/12: Adding TRASH retention statuses to A_SOURCE_FILE_RECEIVED
|
||||||
PROMPT ===============================================================
|
PROMPT ===================================================================
|
||||||
|
@@07_MARS_828_install_add_trash_retention_statuses.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 6/12: Granting privileges on T_FILENAME to MRDS_LOADER
|
||||||
|
PROMPT ==========================================================
|
||||||
|
@@08_MARS_828_install_grant_t_filename.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 7/12: Deploying FILE_ARCHIVER Package Specification v3.3.0
|
||||||
|
PROMPT ==============================================================
|
||||||
@@03_MARS_828_install_CT_MRDS_FILE_ARCHIVER_SPEC.sql
|
@@03_MARS_828_install_CT_MRDS_FILE_ARCHIVER_SPEC.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 4/7: Deploying FILE_ARCHIVER Package Body v3.0.0
|
PROMPT Step 8/14: Deploying FILE_ARCHIVER Package Body v3.3.0
|
||||||
PROMPT ======================================================
|
PROMPT ====================================================
|
||||||
@@04_MARS_828_install_CT_MRDS_FILE_ARCHIVER_BODY.sql
|
@@04_MARS_828_install_CT_MRDS_FILE_ARCHIVER_BODY.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 5/7: Verifying installation
|
PROMPT Step 9/14: Deploying FILE_MANAGER Package Specification v3.3.2
|
||||||
PROMPT =================================
|
PROMPT =============================================================
|
||||||
|
@@09_MARS_828_install_CT_MRDS_FILE_MANAGER_SPEC.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 10/14: Deploying FILE_MANAGER Package Body v3.3.2
|
||||||
|
PROMPT ===================================================
|
||||||
|
@@10_MARS_828_install_CT_MRDS_FILE_MANAGER_BODY.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 11/14: Verifying installation
|
||||||
|
PROMPT ==================================
|
||||||
@@05_MARS_828_verify_installation.sql
|
@@05_MARS_828_verify_installation.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 6/7: Tracking package versions
|
PROMPT Step 12/14: Tracking package versions
|
||||||
PROMPT ====================================
|
PROMPT =====================================
|
||||||
@@track_package_versions.sql
|
@@track_package_versions.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 7/7: Verifying tracked packages
|
PROMPT Step 13/14: Verifying tracked packages
|
||||||
PROMPT =====================================
|
PROMPT ======================================
|
||||||
@@verify_packages_version.sql
|
@@verify_packages_version.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 14/14: Configuring Release 01 tables archival strategies
|
||||||
|
PROMPT ============================================================
|
||||||
|
@@06_MARS_828_configure_release01_tables.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
PROMPT MARS-828 Installation Completed
|
PROMPT MARS-828 Installation Completed
|
||||||
@@ -96,17 +133,23 @@ PROMPT Completion Time:
|
|||||||
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS install_end FROM DUAL;
|
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS install_end FROM DUAL;
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Installation Summary:
|
PROMPT Installation Summary:
|
||||||
PROMPT - Package: CT_MRDS.FILE_ARCHIVER
|
PROMPT - Packages Installed:
|
||||||
PROMPT - Version: 2.0.0 -> 3.0.0 (MAJOR)
|
PROMPT * CT_MRDS.FILE_ARCHIVER v3.3.0 (includes selective archiving and config-based TRASH policy)
|
||||||
PROMPT - New Strategies: CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID
|
PROMPT * CT_MRDS.FILE_MANAGER v3.3.2 (compatible with MARS-828 threshold column renames)
|
||||||
PROMPT - Backward Compatible: THRESHOLD_BASED (default)
|
PROMPT - Strategies: THRESHOLD_BASED (default), MINIMUM_AGE_MONTHS (0=current month), HYBRID
|
||||||
|
PROMPT - Selective Archiving: IS_ARCHIVE_ENABLED column (Y=archive, N=skip)
|
||||||
|
PROMPT - TRASH Policy: IS_KEEP_IN_TRASH column (Y=keep files, N=delete immediately)
|
||||||
|
PROMPT * Default: IS_ARCHIVE_ENABLED='Y', IS_KEEP_IN_TRASH='N' (archiving enabled, immediate deletion)
|
||||||
|
PROMPT * TRASH is a subfolder in DATA bucket (e.g., TRASH/LM/TABLE_NAME)
|
||||||
|
PROMPT * No more pKeepInTrash parameter - policy from config only
|
||||||
|
PROMPT - New Procedure: ARCHIVE_ALL_FOR_SOURCE(pSourceKey) for batch processing
|
||||||
|
PROMPT - TRASH Management: RESTORE_FILE_FROM_TRASH, PURGE_TRASH_FOLDER (3-level granularity)
|
||||||
|
PROMPT - New Statuses: ARCHIVED_AND_TRASHED, ARCHIVED_AND_PURGED
|
||||||
|
PROMPT - Backward Compatible: Yes (default THRESHOLD_BASED, existing behavior preserved)
|
||||||
|
PROMPT - Configured Tables: 25 Release 01 tables (19 LM + 6 CSDB)
|
||||||
|
PROMPT - Includes All Fixes from v3.0.0 through v3.2.1
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Next Steps:
|
PROMPT Note: Incremental patches available in patches/ directory
|
||||||
PROMPT 1. Configure archival strategies per source:
|
|
||||||
PROMPT UPDATE A_SOURCE_FILE_CONFIG SET ARCHIVAL_STRATEGY = 'CURRENT_MONTH_ONLY' WHERE A_SOURCE_KEY = 'LM';
|
|
||||||
PROMPT UPDATE A_SOURCE_FILE_CONFIG SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS', MINIMUM_AGE_MONTHS = 6 WHERE A_SOURCE_KEY = 'CSDB';
|
|
||||||
PROMPT 2. Test strategies using test_archival_strategies.sql
|
|
||||||
PROMPT 3. Monitor first archival run
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Log file: &_filename
|
PROMPT Log file: &_filename
|
||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
|
|||||||
@@ -1,310 +0,0 @@
|
|||||||
|
|
||||||
============================================================================
|
|
||||||
MARS-828 Installation Starting (AUTO MODE)
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
INSTALL_START
|
|
||||||
______________________
|
|
||||||
2026-01-28 06:49:11
|
|
||||||
|
|
||||||
1 row selected.
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Step 1/7: Adding archival strategy columns
|
|
||||||
===================================================================
|
|
||||||
========================================
|
|
||||||
MARS-828: Adding archival strategy columns
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Error starting at line : 11 File @ C:\_git\_local_rep\working_dir_02\MARS_Packages\REL01_ADDITIONS\MARS-828\01_MARS_828_install_add_archival_strategy_columns.sql
|
|
||||||
In command -
|
|
||||||
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD (
|
|
||||||
ARCHIVAL_STRATEGY VARCHAR2(30) DEFAULT 'THRESHOLD_BASED' NOT NULL,
|
|
||||||
MINIMUM_AGE_MONTHS NUMBER(3) DEFAULT NULL
|
|
||||||
)
|
|
||||||
Error report -
|
|
||||||
ORA-01430: column being added already exists in table
|
|
||||||
|
|
||||||
https://docs.oracle.com/error-help/db/ora-01430/
|
|
||||||
01430. 00000 - "column being added already exists in table"
|
|
||||||
*Cause: An ALTER TABLE ADD statement specified the name of a
|
|
||||||
column that was already in the table. All column names must be
|
|
||||||
unique within a table.
|
|
||||||
*Action: Specify a unique name for the new column, then
|
|
||||||
re-execute the statement.
|
|
||||||
|
|
||||||
Error starting at line : 17 File @ C:\_git\_local_rep\working_dir_02\MARS_Packages\REL01_ADDITIONS\MARS-828\01_MARS_828_install_add_archival_strategy_columns.sql
|
|
||||||
In command -
|
|
||||||
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD CONSTRAINT
|
|
||||||
CHK_ARCHIVAL_STRATEGY CHECK (
|
|
||||||
ARCHIVAL_STRATEGY IN ('THRESHOLD_BASED', 'CURRENT_MONTH_ONLY', 'MINIMUM_AGE_MONTHS', 'HYBRID')
|
|
||||||
)
|
|
||||||
Error report -
|
|
||||||
ORA-02264: name already used by an existing constraint
|
|
||||||
|
|
||||||
https://docs.oracle.com/error-help/db/ora-02264/
|
|
||||||
02264. 00000 - "name already used by an existing constraint"
|
|
||||||
*Cause: The specified constraint name has to be unique.
|
|
||||||
*Action: Specify a unique constraint name for the constraint.
|
|
||||||
|
|
||||||
Comment created.
|
|
||||||
|
|
||||||
|
|
||||||
Comment created.
|
|
||||||
|
|
||||||
|
|
||||||
COLUMN_NAME DATA_TYPE DATA_LENGTH NULLABLE DATA_DEFAULT
|
|
||||||
_____________________ ____________ ______________ ___________ _____________________
|
|
||||||
ARCHIVAL_STRATEGY VARCHAR2 30 N 'THRESHOLD_BASED'
|
|
||||||
MINIMUM_AGE_MONTHS NUMBER 22 Y NULL
|
|
||||||
|
|
||||||
2 rows selected.
|
|
||||||
|
|
||||||
========================================
|
|
||||||
Archival strategy columns added successfully
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Step 2/7: Creating validation trigger
|
|
||||||
======================================
|
|
||||||
========================================
|
|
||||||
MARS-828: Creating archival strategy validation trigger
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Trigger CT_MRDS.TRG_BI_A_SRC_FILE_CFG_ARCH_VAL compiled
|
|
||||||
|
|
||||||
|
|
||||||
TRIGGER_NAME STATUS TRIGGER_TYPE TRIGGERING_EVENT
|
|
||||||
_________________________________ __________ __________________ ___________________
|
|
||||||
TRG_BI_A_SRC_FILE_CFG_ARCH_VAL ENABLED BEFORE EACH ROW INSERT OR UPDATE
|
|
||||||
|
|
||||||
1 row selected.
|
|
||||||
|
|
||||||
========================================
|
|
||||||
Archival strategy validation trigger created successfully
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Step 3/7: Deploying FILE_ARCHIVER Spec v3.0.0
|
|
||||||
===============================================================
|
|
||||||
|
|
||||||
Package CT_MRDS.FILE_ARCHIVER compiled
|
|
||||||
|
|
||||||
========================================
|
|
||||||
FILE_ARCHIVER Specification v3.0.0 ready for installation
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Step 4/7: Deploying FILE_ARCHIVER Body v3.0.0
|
|
||||||
======================================================
|
|
||||||
|
|
||||||
Package Body CT_MRDS.FILE_ARCHIVER compiled
|
|
||||||
|
|
||||||
LINE/COL ERROR
|
|
||||||
--------- -------------------------------------------------------------
|
|
||||||
36/10 PLS-00103: Encountered the symbol "\" when expecting one of the following: ( begin case declare else end exit for goto if loop mod null pragma raise return select update when while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge json_object The symbol "case was inserted before "\" to continue.
|
|
||||||
49/8 PLS-00103: Encountered the symbol "GET_ARCHIVAL_WHERE_CLAUSE" when expecting one of the following: case
|
|
||||||
67/9 PLS-00103: Encountered the symbol "JOIN" when expecting one of the following: , ; for group having intersect minus order start union where connect
|
|
||||||
Errors: check compiler log
|
|
||||||
|
|
||||||
Step 5/7: Verifying installation
|
|
||||||
=================================
|
|
||||||
========================================
|
|
||||||
MARS-828: Verification Script
|
|
||||||
========================================
|
|
||||||
|
|
||||||
1. Verifying A_SOURCE_FILE_CONFIG columns...
|
|
||||||
|
|
||||||
COLUMN_NAME DATA_TYPE NULLABLE DATA_DEFAULT
|
|
||||||
_____________________ ____________ ___________ _____________________
|
|
||||||
ARCHIVAL_STRATEGY VARCHAR2 N 'THRESHOLD_BASED'
|
|
||||||
MINIMUM_AGE_MONTHS NUMBER Y NULL
|
|
||||||
|
|
||||||
2 rows selected.
|
|
||||||
|
|
||||||
|
|
||||||
2. Verifying check constraint...
|
|
||||||
|
|
||||||
CONSTRAINT_NAME CONSTRAINT_TYPE SEARCH_CONDITION
|
|
||||||
________________________ __________________ _________________________________________________________________________________________________
|
|
||||||
CHK_ARCHIVAL_STRATEGY C ARCHIVAL_STRATEGY IN ('THRESHOLD_BASED', 'CURRENT_MONTH_ONLY', 'MINIMUM_AGE_MONTHS', 'HYBRID')
|
|
||||||
|
|
||||||
1 row selected.
|
|
||||||
|
|
||||||
|
|
||||||
3. Verifying validation trigger...
|
|
||||||
|
|
||||||
TRIGGER_NAME STATUS TRIGGER_TYPE
|
|
||||||
_________________________________ __________ __________________
|
|
||||||
TRG_BI_A_SRC_FILE_CFG_ARCH_VAL ENABLED BEFORE EACH ROW
|
|
||||||
|
|
||||||
1 row selected.
|
|
||||||
|
|
||||||
|
|
||||||
4. Checking FILE_ARCHIVER package status...
|
|
||||||
|
|
||||||
OBJECT_NAME OBJECT_TYPE STATUS LAST_DDL_TIME
|
|
||||||
________________ _______________ __________ ______________________
|
|
||||||
FILE_ARCHIVER PACKAGE VALID 2026-01-28 06:49:14
|
|
||||||
FILE_ARCHIVER PACKAGE BODY INVALID 2026-01-28 06:49:15
|
|
||||||
|
|
||||||
2 rows selected.
|
|
||||||
|
|
||||||
|
|
||||||
5. Checking for compilation errors...
|
|
||||||
|
|
||||||
NAME TYPE LINE POSITION TEXT
|
|
||||||
________________ _______________ _______ ___________ _____________________________________________________________________________
|
|
||||||
FILE_ARCHIVER PACKAGE BODY 36 10 PLS-00103: Encountered the symbol "\" when expecting one of the following:
|
|
||||||
|
|
||||||
( begin case declare else end exit for goto if loop mod null
|
|
||||||
pragma raise return select update when while with
|
|
||||||
<an identifier> <a double-quoted delimited-identifier>
|
|
||||||
<a bind variable> << continue close current delete fetch lock
|
|
||||||
insert open rollback savepoint set sql execute commit forall
|
|
||||||
merge pipe purge json_object
|
|
||||||
The symbol "case was inserted before "\" to continue.
|
|
||||||
|
|
||||||
FILE_ARCHIVER PACKAGE BODY 49 8 PLS-00103: Encountered the symbol "GET_ARCHIVAL_WHERE_CLAUSE" when expecting one of the following:
|
|
||||||
|
|
||||||
case
|
|
||||||
|
|
||||||
FILE_ARCHIVER PACKAGE BODY 67 9 PLS-00103: Encountered the symbol "JOIN" when expecting one of the following:
|
|
||||||
|
|
||||||
, ; for group having intersect minus order start union where
|
|
||||||
connect
|
|
||||||
|
|
||||||
|
|
||||||
3 rows selected.
|
|
||||||
|
|
||||||
|
|
||||||
6. Verifying FILE_ARCHIVER version...
|
|
||||||
|
|
||||||
Error starting at line : 79 File @ C:\_git\_local_rep\working_dir_02\MARS_Packages\REL01_ADDITIONS\MARS-828\05_MARS_828_verify_installation.sql
|
|
||||||
In command -
|
|
||||||
SELECT CT_MRDS.FILE_ARCHIVER.GET_VERSION() as package_version FROM DUAL
|
|
||||||
Error at Command Line : 79 Column : 68 File @ C:\_git\_local_rep\working_dir_02\MARS_Packages\REL01_ADDITIONS\MARS-828\05_MARS_828_verify_installation.sql
|
|
||||||
Error report -
|
|
||||||
SQL Error: ORA-04063: package body "CT_MRDS.FILE_ARCHIVER" has errors
|
|
||||||
|
|
||||||
https://docs.oracle.com/error-help/db/ora-04063/04063. 00000 - "%s has errors"
|
|
||||||
*Cause: Attempt to execute a stored procedure or use a view that has
|
|
||||||
errors. For stored procedures, the problem could be syntax errors
|
|
||||||
or references to other, non-existent procedures. For views,
|
|
||||||
the problem could be a reference in the view's defining query to
|
|
||||||
a non-existent table.
|
|
||||||
Can also be a table which has references to non-existent or
|
|
||||||
inaccessible types.
|
|
||||||
*Action: Fix the errors and/or create referenced objects as necessary.
|
|
||||||
|
|
||||||
More Details :
|
|
||||||
https://docs.oracle.com/error-help/db/ora-04063/
|
|
||||||
|
|
||||||
7. Testing trigger validation (should fail)...
|
|
||||||
SUCCESS: Trigger validation working correctly
|
|
||||||
Expected error: ORA-20999: MINIMUM_AGE_MONTHS is required for MINIMUM_AGE_MONTHS strategy
|
|
||||||
ORA-06512: at "CT_MRDS.TRG_BI_A_SRC_FILE_CFG_ARCH_VAL", line 26
|
|
||||||
ORA-06512: at "CT_MRDS.TRG_BI_A_SRC_FILE_CFG_ARCH_VAL", line 8
|
|
||||||
ORA-04088: error during execution of trigger 'CT_MRDS.TRG_BI_A_SRC_FILE_CFG_ARCH_VAL'
|
|
||||||
|
|
||||||
|
|
||||||
PL/SQL procedure successfully completed.
|
|
||||||
|
|
||||||
|
|
||||||
========================================
|
|
||||||
MARS-828: Verification Complete
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Step 6/7: Tracking package versions
|
|
||||||
====================================
|
|
||||||
========================================
|
|
||||||
Package Version Tracking
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Summary:
|
|
||||||
--------
|
|
||||||
Packages tracked: 0/1
|
|
||||||
========================================
|
|
||||||
|
|
||||||
|
|
||||||
PL/SQL procedure successfully completed.
|
|
||||||
|
|
||||||
|
|
||||||
Step 7/7: Verifying tracked packages
|
|
||||||
=====================================
|
|
||||||
|
|
||||||
========================================
|
|
||||||
Package Version Verification
|
|
||||||
========================================
|
|
||||||
|
|
||||||
|
|
||||||
PACKAGE_OWNER PACKAGE_NAME VERSION STATUS
|
|
||||||
________________ ___________________ __________ _______________________________________________________
|
|
||||||
CT_MRDS DATA_EXPORTER 2.5.0 OK: Package CT_MRDS.DATA_EXPORTER has not changed.
|
|
||||||
Last Tracked: 2026-01-26 17:15:41
|
|
||||||
Version: 2.5.0
|
|
||||||
CT_MRDS ENV_MANAGER 3.2.0 OK: Package CT_MRDS.ENV_MANAGER has not changed.
|
|
||||||
Last Tracked: 2026-01-26 17:15:41
|
|
||||||
Version: 3.2.0
|
|
||||||
CT_MRDS FILE_ARCHIVER 2.0.0 WARNING: Package CT_MRDS.FILE_ARCHIVER has changed!
|
|
||||||
========================================
|
|
||||||
Last Tracked Version: 2.0.0
|
|
||||||
Last Tracked Date: 2025-11-25 16:00:36
|
|
||||||
|
|
||||||
SPECIFICATION Changed:
|
|
||||||
Current Hash: 71a835e531971ca7...
|
|
||||||
Last Hash: 836641155e237fc5...
|
|
||||||
|
|
||||||
BODY Changed:
|
|
||||||
Current Hash: 6f87dff6b0394529...
|
|
||||||
Last Hash: 9bf9b3c0e059493c...
|
|
||||||
|
|
||||||
RECOMMENDATION:
|
|
||||||
1. Update PACKAGE_VERSION constant
|
|
||||||
2. Update PACKAGE_BUILD_DATE constant
|
|
||||||
3. Add entry to VERSION_HISTORY
|
|
||||||
4. Call TRACK_PACKAGE_VERSION to update tracking
|
|
||||||
CT_MRDS FILE_MANAGER 3.4.0 OK: Package CT_MRDS.FILE_MANAGER has not changed.
|
|
||||||
Last Tracked: 2026-01-26 11:42:32
|
|
||||||
Version: 3.4.0
|
|
||||||
CT_MRDS WORKFLOW_MANAGER 1.7.1 OK: Package CT_MRDS.WORKFLOW_MANAGER has not changed.
|
|
||||||
Last Tracked: 2025-11-25 16:00:36
|
|
||||||
Version: 1.7.1
|
|
||||||
ODS FILE_MANAGER_ODS 2.1.0 WARNING: Package ODS.FILE_MANAGER_ODS has changed!
|
|
||||||
========================================
|
|
||||||
Last Tracked Version: 2.1.0
|
|
||||||
Last Tracked Date: 2025-11-26 08:58:57
|
|
||||||
|
|
||||||
BODY Changed:
|
|
||||||
Current Hash: 1d167a53256c10dd...
|
|
||||||
Last Hash: NULL...
|
|
||||||
|
|
||||||
RECOMMENDATION:
|
|
||||||
1. Update PACKAGE_VERSION constant
|
|
||||||
2. Update PACKAGE_BUILD_DATE constant
|
|
||||||
3. Add entry to VERSION_HISTORY
|
|
||||||
4. Call TRACK_PACKAGE_VERSION to update tracking
|
|
||||||
EnvironmentID set to: dev
|
|
||||||
|
|
||||||
|
|
||||||
========================================
|
|
||||||
Verification Complete
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Legend:
|
|
||||||
OK - Package has not changed since last tracking
|
|
||||||
WARNING - Package code changed without version update
|
|
||||||
|
|
||||||
For detailed hash information, use:
|
|
||||||
SELECT ENV_MANAGER.GET_PACKAGE_HASH_INFO('OWNER', 'PACKAGE') FROM DUAL
|
|
||||||
========================================
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
MARS-828 Installation Completed
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
INSTALL_END
|
|
||||||
______________________
|
|
||||||
2026-01-28 06:49:23
|
|
||||||
|
|
||||||
1 row selected.
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
|
|
||||||
============================================================================
|
|
||||||
MARS-828 Rollback Starting (AUTO MODE - No Confirmation)
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
ROLLBACK_START
|
|
||||||
______________________
|
|
||||||
2026-01-29 19:52:30
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.065
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Step 1/6: Restoring FILE_ARCHIVER Package Specification v2.0.0
|
|
||||||
===============================================================
|
|
||||||
|
|
||||||
Package CT_MRDS.FILE_ARCHIVER compiled
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.110
|
|
||||||
|
|
||||||
Step 2/6: Restoring FILE_ARCHIVER Package Body v2.0.0
|
|
||||||
======================================================
|
|
||||||
|
|
||||||
Package Body CT_MRDS.FILE_ARCHIVER compiled
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.133
|
|
||||||
|
|
||||||
Step 3/6: Dropping validation trigger
|
|
||||||
======================================
|
|
||||||
========================================
|
|
||||||
MARS-828: Dropping archival strategy validation trigger
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Error starting at line : 10 File @ C:\_git\_local_rep\working_dir_02\MARS_Packages\REL01_ADDITIONS\MARS-828\93_MARS_828_rollback_trigger.sql
|
|
||||||
In command -
|
|
||||||
DROP TRIGGER CT_MRDS.TRG_BI_A_SRC_FILE_CFG_ARCH_VAL
|
|
||||||
Error report -
|
|
||||||
ORA-04080: trigger 'TRG_BI_A_SRC_FILE_CFG_ARCH_VAL' does not exist
|
|
||||||
|
|
||||||
https://docs.oracle.com/error-help/db/ora-04080/
|
|
||||||
04080. 00000 - "trigger '%s' does not exist"
|
|
||||||
*Cause: The TRIGGER name is invalid.
|
|
||||||
*Action: Check the trigger name.
|
|
||||||
Elapsed: 00:00:00.135
|
|
||||||
|
|
||||||
TRIGGER_COUNT
|
|
||||||
________________
|
|
||||||
0
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.070
|
|
||||||
========================================
|
|
||||||
Validation trigger dropped successfully
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Step 4/6: Dropping archival strategy columns
|
|
||||||
=============================================
|
|
||||||
========================================
|
|
||||||
MARS-828: Removing archival strategy columns
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Error starting at line : 11 File @ C:\_git\_local_rep\working_dir_02\MARS_Packages\REL01_ADDITIONS\MARS-828\94_MARS_828_rollback_columns.sql
|
|
||||||
In command -
|
|
||||||
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
|
||||||
DROP CONSTRAINT CHK_ARCHIVAL_STRATEGY
|
|
||||||
Error report -
|
|
||||||
ORA-02443: Cannot drop constraint - nonexistent constraint
|
|
||||||
|
|
||||||
https://docs.oracle.com/error-help/db/ora-02443/
|
|
||||||
02443. 00000 - "Cannot drop constraint - nonexistent constraint"
|
|
||||||
*Cause: alter table drop constraint <constraint_name>
|
|
||||||
*Action: make sure you supply correct constraint name.
|
|
||||||
Elapsed: 00:00:00.118
|
|
||||||
|
|
||||||
Error starting at line : 15 File @ C:\_git\_local_rep\working_dir_02\MARS_Packages\REL01_ADDITIONS\MARS-828\94_MARS_828_rollback_columns.sql
|
|
||||||
In command -
|
|
||||||
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG DROP (
|
|
||||||
ARCHIVAL_STRATEGY,
|
|
||||||
MINIMUM_AGE_MONTHS
|
|
||||||
)
|
|
||||||
Error report -
|
|
||||||
ORA-00904: "MINIMUM_AGE_MONTHS": invalid identifier
|
|
||||||
|
|
||||||
https://docs.oracle.com/error-help/db/ora-00904/
|
|
||||||
00904. 00000 - "%s: invalid identifier"
|
|
||||||
*Cause: The identifier or column name entered was invalid.
|
|
||||||
*Action: Ensure the following
|
|
||||||
Elapsed: 00:00:00.113
|
|
||||||
|
|
||||||
no rows selected
|
|
||||||
Elapsed: 00:00:00.066
|
|
||||||
========================================
|
|
||||||
Archival strategy columns removed successfully
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Step 5/6: Tracking rollback version
|
|
||||||
====================================
|
|
||||||
========================================
|
|
||||||
Package Version Tracking
|
|
||||||
========================================
|
|
||||||
EnvironmentID set to: dev
|
|
||||||
[2026-01-29 19:52:34] [INFO] ENV_MANAGER.TRACK_PACKAGE_VERSION: Start TRACK_PACKAGE_VERSION
|
|
||||||
[2026-01-29 19:52:34] [INFO] ENV_MANAGER.TRACK_PACKAGE_VERSION: End TRACK_PACKAGE_VERSION - Record inserted
|
|
||||||
|
|
||||||
Summary:
|
|
||||||
--------
|
|
||||||
Packages tracked: 1/1
|
|
||||||
|
|
||||||
Tracked Packages:
|
|
||||||
CT_MRDS.FILE_ARCHIVER v2.0.0
|
|
||||||
========================================
|
|
||||||
|
|
||||||
|
|
||||||
PL/SQL procedure successfully completed.
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.232
|
|
||||||
|
|
||||||
Step 6/6: Verifying tracked packages
|
|
||||||
=====================================
|
|
||||||
|
|
||||||
========================================
|
|
||||||
Package Version Verification
|
|
||||||
========================================
|
|
||||||
|
|
||||||
|
|
||||||
PACKAGE_OWNER PACKAGE_NAME VERSION STATUS
|
|
||||||
________________ ___________________ __________ ______________________________________________________
|
|
||||||
CT_MRDS DATA_EXPORTER 2.6.3 OK: Package CT_MRDS.DATA_EXPORTER has not changed.
|
|
||||||
Last Tracked: 2026-01-28 19:18:36
|
|
||||||
Version: 2.6.3
|
|
||||||
CT_MRDS ENV_MANAGER 3.2.0 OK: Package CT_MRDS.ENV_MANAGER has not changed.
|
|
||||||
Last Tracked: 2026-01-28 19:18:36
|
|
||||||
Version: 3.2.0
|
|
||||||
CT_MRDS FILE_ARCHIVER 2.0.0 OK: Package CT_MRDS.FILE_ARCHIVER has not changed.
|
|
||||||
Last Tracked: 2026-01-29 19:52:34
|
|
||||||
Version: 2.0.0
|
|
||||||
CT_MRDS FILE_MANAGER 3.4.0 OK: Package CT_MRDS.FILE_MANAGER has not changed.
|
|
||||||
Last Tracked: 2026-01-26 11:42:32
|
|
||||||
Version: 3.4.0
|
|
||||||
CT_MRDS WORKFLOW_MANAGER 1.7.1 OK: Package CT_MRDS.WORKFLOW_MANAGER has not changed.
|
|
||||||
Last Tracked: 2025-11-25 16:00:36
|
|
||||||
Version: 1.7.1
|
|
||||||
ODS FILE_MANAGER_ODS 2.1.0 WARNING: Package ODS.FILE_MANAGER_ODS has changed!
|
|
||||||
========================================
|
|
||||||
Last Tracked Version: 2.1.0
|
|
||||||
Last Tracked Date: 2025-11-26 08:58:57
|
|
||||||
|
|
||||||
BODY Changed:
|
|
||||||
Current Hash: 1d167a53256c10dd...
|
|
||||||
Last Hash: NULL...
|
|
||||||
|
|
||||||
RECOMMENDATION:
|
|
||||||
1. Update PACKAGE_VERSION constant
|
|
||||||
2. Update PACKAGE_BUILD_DATE constant
|
|
||||||
3. Add entry to VERSION_HISTORY
|
|
||||||
4. Call TRACK_PACKAGE_VERSION to update tracking
|
|
||||||
Elapsed: 00:00:00.388
|
|
||||||
|
|
||||||
========================================
|
|
||||||
Verification Complete
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Legend:
|
|
||||||
OK - Package has not changed since last tracking
|
|
||||||
WARNING - Package code changed without version update
|
|
||||||
|
|
||||||
For detailed hash information, use:
|
|
||||||
SELECT ENV_MANAGER.GET_PACKAGE_HASH_INFO('OWNER', 'PACKAGE') FROM DUAL
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Verification: Package Compilation Status
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
OBJECT_NAME OBJECT_TYPE STATUS LAST_DDL_TIME
|
|
||||||
________________ _______________ _________ ________________
|
|
||||||
FILE_ARCHIVER PACKAGE VALID 29-JAN-26
|
|
||||||
FILE_ARCHIVER PACKAGE BODY VALID 29-JAN-26
|
|
||||||
|
|
||||||
2 rows selected.
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.100
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
MARS-828 Rollback Completed
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
ROLLBACK_END
|
|
||||||
______________________
|
|
||||||
2026-01-29 19:52:36
|
|
||||||
|
|
||||||
1 row selected.
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.058
|
|
||||||
|
|
||||||
Log file: ../log/ROLLBACK_MARS_828_AUTO_G45C5E88148E17E_GGMICHALSKI_20260129_195230.log
|
|
||||||
============================================================================
|
|
||||||
@@ -1,197 +0,0 @@
|
|||||||
|
|
||||||
============================================================================
|
|
||||||
MARS-828 Rollback Starting
|
|
||||||
============================================================================
|
|
||||||
WARNING: This will restore FILE_ARCHIVER to v2.0.0
|
|
||||||
|
|
||||||
CRITICAL IMPACT:
|
|
||||||
1. All archival strategies revert to THRESHOLD_BASED
|
|
||||||
2. ARCHIVAL_STRATEGY and MINIMUM_AGE_MONTHS columns will be dropped
|
|
||||||
3. Validation trigger will be removed
|
|
||||||
4. Reconfigure archival thresholds after rollback
|
|
||||||
|
|
||||||
Timestamp:
|
|
||||||
|
|
||||||
ROLLBACK_START
|
|
||||||
______________________
|
|
||||||
2026-01-29 19:52:12
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.068
|
|
||||||
============================================================================
|
|
||||||
Type YES to continue with rollback, or Ctrl+C to abort: YES
|
|
||||||
old:BEGIN
|
|
||||||
IF '&continue' IS NULL OR TRIM('&continue') IS NULL OR UPPER(TRIM('&continue')) != 'YES' THEN
|
|
||||||
RAISE_APPLICATION_ERROR(-20001, 'Rollback aborted by user');
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
|
|
||||||
new:BEGIN
|
|
||||||
IF 'YES' IS NULL OR TRIM('YES') IS NULL OR UPPER(TRIM('YES')) != 'YES' THEN
|
|
||||||
RAISE_APPLICATION_ERROR(-20001, 'Rollback aborted by user');
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
|
|
||||||
PL/SQL procedure successfully completed.
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.096
|
|
||||||
|
|
||||||
Step 1/6: Restoring FILE_ARCHIVER Package Specification v2.0.0
|
|
||||||
===============================================================
|
|
||||||
|
|
||||||
Package CT_MRDS.FILE_ARCHIVER compiled
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.382
|
|
||||||
|
|
||||||
Step 2/6: Restoring FILE_ARCHIVER Package Body v2.0.0
|
|
||||||
======================================================
|
|
||||||
|
|
||||||
Package Body CT_MRDS.FILE_ARCHIVER compiled
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.288
|
|
||||||
|
|
||||||
Step 3/6: Dropping validation trigger
|
|
||||||
======================================
|
|
||||||
========================================
|
|
||||||
MARS-828: Dropping archival strategy validation trigger
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Trigger CT_MRDS.TRG_BI_A_SRC_FILE_CFG_ARCH_VAL dropped.
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.193
|
|
||||||
|
|
||||||
TRIGGER_COUNT
|
|
||||||
________________
|
|
||||||
0
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.335
|
|
||||||
========================================
|
|
||||||
Validation trigger dropped successfully
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Step 4/6: Dropping archival strategy columns
|
|
||||||
=============================================
|
|
||||||
========================================
|
|
||||||
MARS-828: Removing archival strategy columns
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Table CT_MRDS.A_SOURCE_FILE_CONFIG altered.
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.131
|
|
||||||
|
|
||||||
Table CT_MRDS.A_SOURCE_FILE_CONFIG altered.
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.206
|
|
||||||
|
|
||||||
no rows selected
|
|
||||||
Elapsed: 00:00:00.341
|
|
||||||
========================================
|
|
||||||
Archival strategy columns removed successfully
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Step 5/6: Tracking rollback version
|
|
||||||
====================================
|
|
||||||
========================================
|
|
||||||
Package Version Tracking
|
|
||||||
========================================
|
|
||||||
EnvironmentID set to: dev
|
|
||||||
[2026-01-29 19:52:16] [INFO] ENV_MANAGER.TRACK_PACKAGE_VERSION: Start TRACK_PACKAGE_VERSION
|
|
||||||
[2026-01-29 19:52:17] [INFO] ENV_MANAGER.TRACK_PACKAGE_VERSION: End TRACK_PACKAGE_VERSION - Record inserted
|
|
||||||
|
|
||||||
Summary:
|
|
||||||
--------
|
|
||||||
Packages tracked: 1/1
|
|
||||||
|
|
||||||
Tracked Packages:
|
|
||||||
CT_MRDS.FILE_ARCHIVER v2.0.0
|
|
||||||
========================================
|
|
||||||
|
|
||||||
|
|
||||||
PL/SQL procedure successfully completed.
|
|
||||||
|
|
||||||
Elapsed: 00:00:01.230
|
|
||||||
|
|
||||||
Step 6/6: Verifying tracked packages
|
|
||||||
=====================================
|
|
||||||
|
|
||||||
========================================
|
|
||||||
Package Version Verification
|
|
||||||
========================================
|
|
||||||
|
|
||||||
|
|
||||||
PACKAGE_OWNER PACKAGE_NAME VERSION STATUS
|
|
||||||
________________ ___________________ __________ ______________________________________________________
|
|
||||||
CT_MRDS DATA_EXPORTER 2.6.3 OK: Package CT_MRDS.DATA_EXPORTER has not changed.
|
|
||||||
Last Tracked: 2026-01-28 19:18:36
|
|
||||||
Version: 2.6.3
|
|
||||||
CT_MRDS ENV_MANAGER 3.2.0 OK: Package CT_MRDS.ENV_MANAGER has not changed.
|
|
||||||
Last Tracked: 2026-01-28 19:18:36
|
|
||||||
Version: 3.2.0
|
|
||||||
CT_MRDS FILE_ARCHIVER 2.0.0 OK: Package CT_MRDS.FILE_ARCHIVER has not changed.
|
|
||||||
Last Tracked: 2026-01-29 19:52:17
|
|
||||||
Version: 2.0.0
|
|
||||||
CT_MRDS FILE_MANAGER 3.4.0 OK: Package CT_MRDS.FILE_MANAGER has not changed.
|
|
||||||
Last Tracked: 2026-01-26 11:42:32
|
|
||||||
Version: 3.4.0
|
|
||||||
CT_MRDS WORKFLOW_MANAGER 1.7.1 OK: Package CT_MRDS.WORKFLOW_MANAGER has not changed.
|
|
||||||
Last Tracked: 2025-11-25 16:00:36
|
|
||||||
Version: 1.7.1
|
|
||||||
ODS FILE_MANAGER_ODS 2.1.0 WARNING: Package ODS.FILE_MANAGER_ODS has changed!
|
|
||||||
========================================
|
|
||||||
Last Tracked Version: 2.1.0
|
|
||||||
Last Tracked Date: 2025-11-26 08:58:57
|
|
||||||
|
|
||||||
BODY Changed:
|
|
||||||
Current Hash: 1d167a53256c10dd...
|
|
||||||
Last Hash: NULL...
|
|
||||||
|
|
||||||
RECOMMENDATION:
|
|
||||||
1. Update PACKAGE_VERSION constant
|
|
||||||
2. Update PACKAGE_BUILD_DATE constant
|
|
||||||
3. Add entry to VERSION_HISTORY
|
|
||||||
4. Call TRACK_PACKAGE_VERSION to update tracking
|
|
||||||
Elapsed: 00:00:00.448
|
|
||||||
|
|
||||||
========================================
|
|
||||||
Verification Complete
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Legend:
|
|
||||||
OK - Package has not changed since last tracking
|
|
||||||
WARNING - Package code changed without version update
|
|
||||||
|
|
||||||
For detailed hash information, use:
|
|
||||||
SELECT ENV_MANAGER.GET_PACKAGE_HASH_INFO('OWNER', 'PACKAGE') FROM DUAL
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Verification: Package Compilation Status
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
OBJECT_NAME OBJECT_TYPE STATUS LAST_DDL_TIME
|
|
||||||
________________ _______________ _________ ________________
|
|
||||||
FILE_ARCHIVER PACKAGE VALID 29-JAN-26
|
|
||||||
FILE_ARCHIVER PACKAGE BODY VALID 29-JAN-26
|
|
||||||
|
|
||||||
2 rows selected.
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.202
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
MARS-828 Rollback Completed
|
|
||||||
============================================================================
|
|
||||||
Completion Time:
|
|
||||||
|
|
||||||
ROLLBACK_END
|
|
||||||
______________________
|
|
||||||
2026-01-29 19:52:20
|
|
||||||
|
|
||||||
1 row selected.
|
|
||||||
|
|
||||||
Elapsed: 00:00:00.061
|
|
||||||
|
|
||||||
Rollback Summary:
|
|
||||||
- Package: CT_MRDS.FILE_ARCHIVER
|
|
||||||
- Restored Version: 2.0.0 (THRESHOLD_BASED archival only)
|
|
||||||
- Removed Features: CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID strategies
|
|
||||||
|
|
||||||
Log file: log/ROLLBACK_MARS_828_G45C5E88148E17E_GGMICHALSKI_20260129_195211.log
|
|
||||||
============================================================================
|
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
-- ====================================================================
|
||||||
|
-- A_SOURCE_FILE_CONFIG Table
|
||||||
|
-- ====================================================================
|
||||||
|
-- Purpose: Store source file configuration and processing rules
|
||||||
|
-- MARS-1049: Added ENCODING column for CSV character set support
|
||||||
|
-- MARS-828: Added ARCHIVAL_STRATEGY and MINIMUM_AGE_MONTHS for archival automation
|
||||||
|
-- ====================================================================
|
||||||
|
|
||||||
|
CREATE TABLE CT_MRDS.A_SOURCE_FILE_CONFIG (
|
||||||
|
A_SOURCE_FILE_CONFIG_KEY NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
A_SOURCE_KEY VARCHAR2(30) NOT NULL ENABLE,
|
||||||
|
SOURCE_FILE_TYPE VARCHAR2(200), -- Can be 'INPUT' or 'CONTAINER' or 'LOAD_CONFIG'
|
||||||
|
SOURCE_FILE_ID VARCHAR2(200),
|
||||||
|
SOURCE_FILE_DESC VARCHAR2(2000),
|
||||||
|
SOURCE_FILE_NAME_PATTERN VARCHAR2(200),
|
||||||
|
TABLE_ID VARCHAR2(200),
|
||||||
|
TEMPLATE_TABLE_NAME VARCHAR2(200),
|
||||||
|
CONTAINER_FILE_KEY NUMBER(38,0),
|
||||||
|
ARCHIVE_THRESHOLD_DAYS NUMBER(4,0),
|
||||||
|
ARCHIVE_THRESHOLD_FILES_COUNT NUMBER(38,0),
|
||||||
|
ARCHIVE_THRESHOLD_BYTES_SUM NUMBER(38,0),
|
||||||
|
ODS_SCHEMA_NAME VARCHAR2(100),
|
||||||
|
ARCHIVE_THRESHOLD_ROWS_COUNT NUMBER(38,0),
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS NUMBER(38,3),
|
||||||
|
ARCHIVAL_STRATEGY VARCHAR2(50),
|
||||||
|
MINIMUM_AGE_MONTHS NUMBER(3,0),
|
||||||
|
ENCODING VARCHAR2(50) DEFAULT 'UTF8',
|
||||||
|
IS_ARCHIVE_ENABLED CHAR(1) DEFAULT 'N' NOT NULL,
|
||||||
|
IS_KEEP_IN_TRASH CHAR(1) DEFAULT 'N' NOT NULL,
|
||||||
|
CONSTRAINT A_SOURCE_FILE_CONFIG_PK PRIMARY KEY (A_SOURCE_FILE_CONFIG_KEY),
|
||||||
|
CONSTRAINT CHK_IS_ARCHIVE_ENABLED CHECK (IS_ARCHIVE_ENABLED IN ('Y', 'N')),
|
||||||
|
CONSTRAINT CHK_IS_KEEP_IN_TRASH CHECK (IS_KEEP_IN_TRASH IN ('Y', 'N')),
|
||||||
|
CONSTRAINT SOURCE_FILE_TYPE_CHK CHECK (SOURCE_FILE_TYPE IN ('INPUT', 'CONTAINER', 'LOAD_CONFIG')),
|
||||||
|
CONSTRAINT ASFC_A_SOURCE_KEY_FK FOREIGN KEY(A_SOURCE_KEY) REFERENCES CT_MRDS.A_SOURCE(A_SOURCE_KEY),
|
||||||
|
CONSTRAINT ASFC_CONTAINER_FILE_KEY_FK FOREIGN KEY(CONTAINER_FILE_KEY) REFERENCES CT_MRDS.A_SOURCE_FILE_CONFIG(A_SOURCE_FILE_CONFIG_KEY),
|
||||||
|
CONSTRAINT A_SOURCE_FILE_CONFIG_UQ1 UNIQUE(SOURCE_FILE_TYPE, SOURCE_FILE_ID, TABLE_ID)
|
||||||
|
) TABLESPACE "DATA";
|
||||||
|
|
||||||
|
-- Primary key index (from production export)
|
||||||
|
CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_FILE_CONFIG_PK"
|
||||||
|
ON "CT_MRDS"."A_SOURCE_FILE_CONFIG" ("A_SOURCE_FILE_CONFIG_KEY")
|
||||||
|
TABLESPACE "DATA";
|
||||||
|
|
||||||
|
-- Unique constraint index (from production export)
|
||||||
|
CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_FILE_CONFIG_UQ1"
|
||||||
|
ON "CT_MRDS"."A_SOURCE_FILE_CONFIG" ("SOURCE_FILE_TYPE", "SOURCE_FILE_ID", "TABLE_ID")
|
||||||
|
TABLESPACE "DATA";
|
||||||
|
|
||||||
|
-- Column comments
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY IS
|
||||||
|
'Primary key - unique identifier for source file configuration record';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_KEY IS
|
||||||
|
'Foreign key to A_SOURCE table - identifies the source system (e.g., LM, C2D, CSDB)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE IS
|
||||||
|
'Type of file configuration: INPUT (data files), CONTAINER (xml files), or LOAD_CONFIG (configuration files)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID IS
|
||||||
|
'Unique identifier for the source file within the source system (e.g., UC_DISSEM, STANDING_FACILITIES)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_DESC IS
|
||||||
|
'Human-readable description of the source file and its purpose';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_NAME_PATTERN IS
|
||||||
|
'Filename pattern for matching incoming files (supports wildcards, e.g., UC_NMA_DISSEM-*.csv)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID IS
|
||||||
|
'Identifier for the target table where data will be loaded (without schema prefix)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.TEMPLATE_TABLE_NAME IS
|
||||||
|
'Fully qualified name of template table in CT_ET_TEMPLATES schema used for external table creation';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.CONTAINER_FILE_KEY IS
|
||||||
|
'Foreign key to parent container configuration when this file is part of an xml (NULL for standalone files)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_DAYS IS
|
||||||
|
'Threshold for THRESHOLD_BASED strategy: archive data older than N days';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_FILES_COUNT IS
|
||||||
|
'Trigger archival when file count exceeds this threshold (used in THRESHOLD_BASED and HYBRID strategies)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_BYTES_SUM IS
|
||||||
|
'Trigger archival when total size in bytes exceeds this threshold (used in THRESHOLD_BASED and HYBRID strategies)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVE_THRESHOLD_ROWS_COUNT IS
|
||||||
|
'Trigger archival when total row count exceeds this threshold (used in THRESHOLD_BASED and HYBRID strategies)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ODS_SCHEMA_NAME IS
|
||||||
|
'Schema name where ODS external tables are created (typically ODS)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.HOURS_TO_EXPIRE_STATISTICS IS
|
||||||
|
'Number of hours before table statistics expire and need to be recalculated';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVAL_STRATEGY IS
|
||||||
|
'Archival strategy: THRESHOLD_BASED (days-based), MINIMUM_AGE_MONTHS (0=current month, N=retain N months), HYBRID (combination)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.MINIMUM_AGE_MONTHS IS
|
||||||
|
'Minimum age in months before archival (required for MINIMUM_AGE_MONTHS and HYBRID strategies, 0=current month only)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING IS
|
||||||
|
'Oracle character set name for CSV files (e.g., UTF8, WE8MSWIN1252, EE8ISO8859P2)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.IS_ARCHIVE_ENABLED IS
|
||||||
|
'Y=Enable archiving, N=Skip archiving. Controls if table participates in archival process';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.IS_KEEP_IN_TRASH IS
|
||||||
|
'Y=Keep files in TRASH after archiving, N=Delete immediately. Controls TRASH retention policy';
|
||||||
|
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON CT_MRDS.A_SOURCE_FILE_CONFIG TO MRDS_LOADER_ROLE;
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
-- ====================================================================
|
||||||
|
-- A_SOURCE_FILE_RECEIVED Table
|
||||||
|
-- ====================================================================
|
||||||
|
-- Purpose: Track received files and their processing status
|
||||||
|
-- ====================================================================
|
||||||
|
|
||||||
|
CREATE TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED (
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
A_SOURCE_FILE_CONFIG_KEY NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
SOURCE_FILE_NAME VARCHAR2(1000) NOT NULL,
|
||||||
|
CHECKSUM VARCHAR2(128),
|
||||||
|
CREATED TIMESTAMP(6) WITH TIME ZONE,
|
||||||
|
BYTES NUMBER,
|
||||||
|
RECEPTION_DATE DATE NOT NULL,
|
||||||
|
PROCESSING_STATUS VARCHAR2(200),
|
||||||
|
EXTERNAL_TABLE_NAME VARCHAR2(200),
|
||||||
|
PARTITION_YEAR VARCHAR2(4),
|
||||||
|
PARTITION_MONTH VARCHAR2(2),
|
||||||
|
ARCH_FILE_NAME VARCHAR2(1000),
|
||||||
|
CONSTRAINT A_SOURCE_FILE_RECEIVED_PK PRIMARY KEY (A_SOURCE_FILE_RECEIVED_KEY),
|
||||||
|
CONSTRAINT ASFR_A_SOURCE_FILE_CONFIG_KEY_FK FOREIGN KEY(A_SOURCE_FILE_CONFIG_KEY) REFERENCES CT_MRDS.A_SOURCE_FILE_CONFIG(A_SOURCE_FILE_CONFIG_KEY),
|
||||||
|
CONSTRAINT A_SOURCE_FILE_RECEIVED_CHK CHECK (PROCESSING_STATUS IN ('RECEIVED', 'VALIDATED', 'READY_FOR_INGESTION', 'INGESTED', 'ARCHIVED', 'ARCHIVED_AND_TRASHED', 'ARCHIVED_AND_PURGED'))
|
||||||
|
) TABLESPACE "DATA";
|
||||||
|
|
||||||
|
-- Unique index for file identification (workaround for TIMESTAMP WITH TIMEZONE constraint limitation)
|
||||||
|
CREATE UNIQUE INDEX CT_MRDS.A_SOURCE_FILE_RECEIVED_UK1
|
||||||
|
ON CT_MRDS.A_SOURCE_FILE_RECEIVED(CHECKSUM, CREATED, BYTES);
|
||||||
|
|
||||||
|
-- Column comments
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY IS
|
||||||
|
'Primary key - unique identifier for received file record';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_CONFIG_KEY IS
|
||||||
|
'Foreign key to A_SOURCE_FILE_CONFIG - links file to its configuration and processing rules';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.SOURCE_FILE_NAME IS
|
||||||
|
'Full object name/path of the received file in OCI Object Storage (includes INBOX prefix)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.CHECKSUM IS
|
||||||
|
'MD5 checksum of file content for integrity verification and duplicate detection';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.CREATED IS
|
||||||
|
'Timestamp with timezone when file was created/uploaded to Object Storage (from DBMS_CLOUD.LIST_OBJECTS)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.BYTES IS
|
||||||
|
'File size in bytes';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.RECEPTION_DATE IS
|
||||||
|
'Date when file was registered in the system (extracted from CREATED timestamp)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PROCESSING_STATUS IS
|
||||||
|
'Current processing status: RECEIVED → VALIDATED → READY_FOR_INGESTION → INGESTED → ARCHIVED_AND_TRASHED → ARCHIVED_AND_PURGED';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.EXTERNAL_TABLE_NAME IS
|
||||||
|
'Name of temporary external table created for file validation (dropped after validation)';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PARTITION_YEAR IS
|
||||||
|
'Year partition value (YYYY format) when file was archived to ARCHIVE bucket with Hive-style partitioning';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PARTITION_MONTH IS
|
||||||
|
'Month partition value (MM format) when file was archived to ARCHIVE bucket with Hive-style partitioning';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.ARCH_FILE_NAME IS
|
||||||
|
'Archive directory prefix in ARCHIVE bucket containing archived Parquet files (supports multiple files from parallel DBMS_CLOUD.EXPORT_DATA)';
|
||||||
|
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON CT_MRDS.A_SOURCE_FILE_RECEIVED TO MRDS_LOADER_ROLE;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -17,39 +17,56 @@ AS
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
||||||
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.1.0';
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.3.0';
|
||||||
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-01-29 21:00:00';
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-11 12:00:00';
|
||||||
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski';
|
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski';
|
||||||
|
|
||||||
-- Version History (Latest changes first)
|
-- Version History (Latest changes first)
|
||||||
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
||||||
|
'3.3.0 (2026-02-11): Added IS_ARCHIVE_ENABLED and IS_KEEP_IN_TRASH columns to A_SOURCE_FILE_CONFIG for selective archiving and config-based TRASH policy. Removed pKeepInTrash parameter (now from config). Added ARCHIVE_ALL batch procedure with 3-level granularity (config/source/all). Added GATHER_TABLE_STAT_ALL batch statistics procedure with 3-level granularity. Added RESTORE_FILE_FROM_TRASH and PURGE_TRASH_FOLDER with 3-level granularity' || CHR(13)||CHR(10) ||
|
||||||
|
'3.2.1 (2026-02-10): Fixed status update - ARCHIVED → ARCHIVED_AND_TRASHED when moving files to TRASH folder (critical bug fix)' || CHR(13)||CHR(10) ||
|
||||||
|
'3.2.0 (2026-02-06): Added pKeepInTrash parameter (DEFAULT TRUE) to ARCHIVE_TABLE_DATA for TRASH folder retention control - files kept in TRASH subfolder (DATA bucket) by default for safety and compliance' || CHR(13)||CHR(10) ||
|
||||||
|
'3.1.2 (2026-02-06): Fixed missing PARTITION_YEAR/PARTITION_MONTH assignments in UPDATE statement and export query circular dependency (now filters by workflow_start instead of partition fields)' || CHR(13)||CHR(10) ||
|
||||||
|
'3.1.1 (2026-02-06): Fixed ORA-01422 error when DBMS_CLOUD.EXPORT_DATA creates multiple parquet files (parallel execution). Now stores archive directory prefix instead of individual filenames' || CHR(13)||CHR(10) ||
|
||||||
'3.1.0 (2026-01-29): Added function overloads for ARCHIVE_TABLE_DATA and GATHER_TABLE_STAT returning SQLCODE for Python library integration' || CHR(13)||CHR(10) ||
|
'3.1.0 (2026-01-29): Added function overloads for ARCHIVE_TABLE_DATA and GATHER_TABLE_STAT returning SQLCODE for Python library integration' || CHR(13)||CHR(10) ||
|
||||||
'3.0.0 (2026-01-27): MARS-828 - Added flexible archival strategies (CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID) via ARCHIVAL_STRATEGY configuration' || CHR(13)||CHR(10) ||
|
'3.0.0 (2026-01-27): MARS-828 - Added flexible archival strategies (MINIMUM_AGE_MONTHS with 0=current month, HYBRID) via ARCHIVAL_STRATEGY configuration' || CHR(13)||CHR(10) ||
|
||||||
'2.0.0 (2025-10-22): Added package versioning system using centralized ENV_MANAGER functions' || CHR(13)||CHR(10) ||
|
'2.0.0 (2025-10-22): Added package versioning system using centralized ENV_MANAGER functions' || CHR(13)||CHR(10) ||
|
||||||
'1.5.0 (2025-10-18): Enhanced ARCHIVE_TABLE_DATA with Hive-style partitioning support' || CHR(13)||CHR(10) ||
|
'1.5.0 (2025-10-18): Enhanced ARCHIVE_TABLE_DATA with Hive-style partitioning support' || CHR(13)||CHR(10) ||
|
||||||
'1.0.0 (2025-09-15): Initial release with table archival and statistics gathering';
|
'1.0.0 (2025-09-15): Initial release with table archival and statistics gathering';
|
||||||
|
|
||||||
cgBL CONSTANT VARCHAR2(2) := ENV_MANAGER.cgBL;
|
cgBL CONSTANT VARCHAR2(2) := ENV_MANAGER.cgBL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_TABLE_STAT
|
||||||
|
* @desc Private function to retrieve table statistics for archival processing.
|
||||||
|
* Returns A_TABLE_STAT record with table metadata and row counts.
|
||||||
|
* @param pSourceFileConfigKey - Configuration key for source file
|
||||||
|
* @return CT_MRDS.A_TABLE_STAT%ROWTYPE - Table statistics record
|
||||||
|
* @private Internal function for archival operations
|
||||||
|
**/
|
||||||
|
FUNCTION GET_TABLE_STAT(pSourceFileConfigKey IN NUMBER) RETURN CT_MRDS.A_TABLE_STAT%ROWTYPE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name ARCHIVE_TABLE_DATA
|
* @name ARCHIVE_TABLE_DATA
|
||||||
* @desc Wrapper procedure for DBMS_CLOUD.EXPORT_DATA.
|
* @desc Wrapper procedure for DBMS_CLOUD.EXPORT_DATA.
|
||||||
* Exports data from table specified by pSourceFileConfigKey(A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY) into PARQUET file on OCI infrustructure.
|
* Exports data from table specified by pSourceFileConfigKey(A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY) into PARQUET file on OCI infrustructure.
|
||||||
* Each YEAR_MONTH pair goes to seperate file (implicit partitioning).
|
* Each YEAR_MONTH pair goes to seperate file (implicit partitioning).
|
||||||
|
* TRASH policy is controlled by A_SOURCE_FILE_CONFIG.IS_KEEP_IN_TRASH column ('Y'=keep in TRASH, 'N'=delete immediately).
|
||||||
**/
|
**/
|
||||||
PROCEDURE ARCHIVE_TABLE_DATA (
|
PROCEDURE ARCHIVE_TABLE_DATA (
|
||||||
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name ARCHIVE_TABLE_DATA
|
* @name FN_ARCHIVE_TABLE_DATA
|
||||||
* @desc Function overload for ARCHIVE_TABLE_DATA procedure.
|
* @desc Function wrapper for ARCHIVE_TABLE_DATA procedure.
|
||||||
* Returns SQLCODE for Python library integration.
|
* Returns SQLCODE for Python library integration.
|
||||||
* Calls the main ARCHIVE_TABLE_DATA procedure and captures execution result.
|
* Calls the main ARCHIVE_TABLE_DATA procedure and captures execution result.
|
||||||
* @example SELECT FILE_ARCHIVER.ARCHIVE_TABLE_DATA(pSourceFileConfigKey => 123) FROM DUAL;
|
* TRASH policy is controlled by A_SOURCE_FILE_CONFIG.IS_KEEP_IN_TRASH column ('Y'=keep in TRASH, 'N'=delete immediately).
|
||||||
|
* @example SELECT FILE_ARCHIVER.FN_ARCHIVE_TABLE_DATA(pSourceFileConfigKey => 123) FROM DUAL;
|
||||||
* @ex_rslt 0 (success) or error code
|
* @ex_rslt 0 (success) or error code
|
||||||
**/
|
**/
|
||||||
FUNCTION ARCHIVE_TABLE_DATA (
|
FUNCTION FN_ARCHIVE_TABLE_DATA (
|
||||||
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
||||||
) RETURN PLS_INTEGER;
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
@@ -65,17 +82,163 @@ AS
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name GATHER_TABLE_STAT
|
* @name FN_GATHER_TABLE_STAT
|
||||||
* @desc Function overload for GATHER_TABLE_STAT procedure.
|
* @desc Function wrapper for GATHER_TABLE_STAT procedure.
|
||||||
* Returns SQLCODE for Python library integration.
|
* Returns SQLCODE for Python library integration.
|
||||||
* Calls the main GATHER_TABLE_STAT procedure and captures execution result.
|
* Calls the main GATHER_TABLE_STAT procedure and captures execution result.
|
||||||
* @example SELECT FILE_ARCHIVER.GATHER_TABLE_STAT(pSourceFileConfigKey => 123) FROM DUAL;
|
* @example SELECT FILE_ARCHIVER.FN_GATHER_TABLE_STAT(pSourceFileConfigKey => 123) FROM DUAL;
|
||||||
* @ex_rslt 0 (success) or error code
|
* @ex_rslt 0 (success) or error code
|
||||||
**/
|
**/
|
||||||
FUNCTION GATHER_TABLE_STAT (
|
FUNCTION FN_GATHER_TABLE_STAT (
|
||||||
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
||||||
) RETURN PLS_INTEGER;
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GATHER_TABLE_STAT_ALL
|
||||||
|
* @desc Multi-level batch statistics gathering procedure with three granularity levels.
|
||||||
|
* Processes configurations based on IS_ARCHIVE_ENABLED setting (when pOnlyEnabled=TRUE).
|
||||||
|
* Gathers statistics for external tables and inserts data into A_TABLE_STAT and A_TABLE_STAT_HIST.
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 1) Gather stats for specific configuration key (highest priority)
|
||||||
|
* @param pSourceKey - (LEVEL 2) Gather stats for all tables in source system (e.g., 'LM', 'C2D') (medium priority)
|
||||||
|
* @param pGatherAll - (LEVEL 3) When TRUE, gather stats for ALL tables across all sources (lowest priority)
|
||||||
|
* @param pOnlyEnabled - When TRUE (default), only process tables with IS_ARCHIVE_ENABLED='Y'
|
||||||
|
* @example -- Level 1: CALL FILE_ARCHIVER.GATHER_TABLE_STAT_ALL(pSourceFileConfigKey => 123);
|
||||||
|
* @example -- Level 2: CALL FILE_ARCHIVER.GATHER_TABLE_STAT_ALL(pSourceKey => 'LM');
|
||||||
|
* @example -- Level 3: CALL FILE_ARCHIVER.GATHER_TABLE_STAT_ALL(pGatherAll => TRUE);
|
||||||
|
* @example -- All tables regardless of IS_ARCHIVE_ENABLED: CALL FILE_ARCHIVER.GATHER_TABLE_STAT_ALL(pGatherAll => TRUE, pOnlyEnabled => FALSE);
|
||||||
|
**/
|
||||||
|
PROCEDURE GATHER_TABLE_STAT_ALL (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE DEFAULT NULL,
|
||||||
|
pGatherAll IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pOnlyEnabled IN BOOLEAN DEFAULT TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name FN_GATHER_TABLE_STAT_ALL
|
||||||
|
* @desc Function wrapper for GATHER_TABLE_STAT_ALL procedure.
|
||||||
|
* Returns SQLCODE for Python library integration.
|
||||||
|
* Calls the main GATHER_TABLE_STAT_ALL procedure and captures execution result.
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 1) Gather stats for specific configuration key (highest priority)
|
||||||
|
* @param pSourceKey - (LEVEL 2) Gather stats for all tables in source system (medium priority)
|
||||||
|
* @param pGatherAll - (LEVEL 3) When TRUE, gather stats for ALL tables across all sources (lowest priority)
|
||||||
|
* @param pOnlyEnabled - When TRUE (default), only process tables with IS_ARCHIVE_ENABLED='Y'
|
||||||
|
* @example SELECT FILE_ARCHIVER.FN_GATHER_TABLE_STAT_ALL(pSourceKey => 'LM') FROM DUAL;
|
||||||
|
* @ex_rslt 0 (success) or error code
|
||||||
|
**/
|
||||||
|
FUNCTION FN_GATHER_TABLE_STAT_ALL (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE DEFAULT NULL,
|
||||||
|
pGatherAll IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pOnlyEnabled IN BOOLEAN DEFAULT TRUE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ARCHIVE_ALL
|
||||||
|
* @desc Multi-level batch archival procedure with three granularity levels.
|
||||||
|
* Only processes configurations where IS_ARCHIVE_ENABLED='Y'.
|
||||||
|
* TRASH policy for each table is controlled by individual IS_KEEP_IN_TRASH column.
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 1) Archive specific configuration key (highest priority)
|
||||||
|
* @param pSourceKey - (LEVEL 2) Archive all enabled tables for source system (e.g., 'LM', 'C2D') (medium priority)
|
||||||
|
* @param pArchiveAll - (LEVEL 3) When TRUE, archive ALL enabled tables across all sources (lowest priority)
|
||||||
|
* @example -- Level 1: CALL FILE_ARCHIVER.ARCHIVE_ALL(pSourceFileConfigKey => 123);
|
||||||
|
* @example -- Level 2: CALL FILE_ARCHIVER.ARCHIVE_ALL(pSourceKey => 'LM');
|
||||||
|
* @example -- Level 3: CALL FILE_ARCHIVER.ARCHIVE_ALL(pArchiveAll => TRUE);
|
||||||
|
**/
|
||||||
|
PROCEDURE ARCHIVE_ALL (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE DEFAULT NULL,
|
||||||
|
pArchiveAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name FN_ARCHIVE_ALL
|
||||||
|
* @desc Function wrapper for ARCHIVE_ALL procedure.
|
||||||
|
* Returns SQLCODE for Python library integration.
|
||||||
|
* Calls the main ARCHIVE_ALL procedure and captures execution result.
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 1) Archive specific configuration key (highest priority)
|
||||||
|
* @param pSourceKey - (LEVEL 2) Archive all enabled tables for source system (medium priority)
|
||||||
|
* @param pArchiveAll - (LEVEL 3) When TRUE, archive ALL enabled tables across all sources (lowest priority)
|
||||||
|
* @example SELECT FILE_ARCHIVER.FN_ARCHIVE_ALL(pSourceKey => 'LM') FROM DUAL;
|
||||||
|
* @ex_rslt 0 (success) or error code
|
||||||
|
**/
|
||||||
|
FUNCTION FN_ARCHIVE_ALL (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE DEFAULT NULL,
|
||||||
|
pArchiveAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name RESTORE_FILE_FROM_TRASH
|
||||||
|
* @desc Restores files from TRASH folder back to ODS at three different granularity levels.
|
||||||
|
* Moves files from TRASH subfolder back to ODS subfolder in DATA bucket.
|
||||||
|
* Updates status from ARCHIVED_AND_TRASHED to INGESTED and clears archival metadata.
|
||||||
|
* @param pSourceFileReceivedKey - (LEVEL 3) Specific file to restore by A_SOURCE_FILE_RECEIVED_KEY (highest priority)
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 2) Restore all files for specific configuration key (medium priority)
|
||||||
|
* @param pRestoreAll - (LEVEL 1) When TRUE, restore ALL files with ARCHIVED_AND_TRASHED status (lowest priority)
|
||||||
|
* @example -- Restore single file: CALL FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pSourceFileReceivedKey => 12345);
|
||||||
|
* @example -- Restore all files for config: CALL FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pSourceFileConfigKey => 341);
|
||||||
|
* @example -- Restore all TRASH globally: CALL FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pRestoreAll => TRUE);
|
||||||
|
**/
|
||||||
|
PROCEDURE RESTORE_FILE_FROM_TRASH (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pRestoreAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name RESTORE_FILE_FROM_TRASH
|
||||||
|
* @desc Function overload for RESTORE_FILE_FROM_TRASH procedure.
|
||||||
|
* Returns SQLCODE for Python library integration.
|
||||||
|
* Calls the main RESTORE_FILE_FROM_TRASH procedure and captures execution result.
|
||||||
|
* @param pSourceFileReceivedKey - (LEVEL 3) Specific file to restore by A_SOURCE_FILE_RECEIVED_KEY (highest priority)
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 2) Restore all files for specific configuration key (medium priority)
|
||||||
|
* @param pRestoreAll - (LEVEL 1) When TRUE, restore ALL files with ARCHIVED_AND_TRASHED status (lowest priority)
|
||||||
|
* @example SELECT FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pSourceFileReceivedKey => 12345) FROM DUAL;
|
||||||
|
* @ex_rslt 0 (success) or error code
|
||||||
|
**/
|
||||||
|
FUNCTION RESTORE_FILE_FROM_TRASH (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pRestoreAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name PURGE_TRASH_FOLDER
|
||||||
|
* @desc Deletes files from TRASH folder at three different granularity levels.
|
||||||
|
* Updates status from ARCHIVED_AND_TRASHED to ARCHIVED_AND_PURGED for all affected files.
|
||||||
|
* WARNING: This operation is irreversible - files are permanently deleted from TRASH.
|
||||||
|
* @param pSourceFileReceivedKey - (LEVEL 3) Specific file to delete by A_SOURCE_FILE_RECEIVED_KEY (highest priority)
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 2) Delete all files for specific configuration key (medium priority)
|
||||||
|
* @param pPurgeAll - (LEVEL 1) When TRUE, delete ALL files with ARCHIVED_AND_TRASHED status (lowest priority)
|
||||||
|
* @example -- Delete single file: CALL FILE_ARCHIVER.PURGE_TRASH_FOLDER(pSourceFileReceivedKey => 12345);
|
||||||
|
* @example -- Delete all files for config: CALL FILE_ARCHIVER.PURGE_TRASH_FOLDER(pSourceFileConfigKey => 341);
|
||||||
|
* @example -- Delete all TRASH globally: CALL FILE_ARCHIVER.PURGE_TRASH_FOLDER(pPurgeAll => TRUE);
|
||||||
|
**/
|
||||||
|
PROCEDURE PURGE_TRASH_FOLDER (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pPurgeAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name PURGE_TRASH_FOLDER
|
||||||
|
* @desc Function overload for PURGE_TRASH_FOLDER procedure.
|
||||||
|
* Returns SQLCODE for Python library integration.
|
||||||
|
* Calls the main PURGE_TRASH_FOLDER procedure and captures execution result.
|
||||||
|
* WARNING: This operation is irreversible - files are permanently deleted from TRASH.
|
||||||
|
* @param pSourceFileReceivedKey - (LEVEL 3) Specific file to delete by A_SOURCE_FILE_RECEIVED_KEY (highest priority)
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 2) Delete all files for specific configuration key (medium priority)
|
||||||
|
* @param pPurgeAll - (LEVEL 1) When TRUE, delete ALL files with ARCHIVED_AND_TRASHED status (lowest priority)
|
||||||
|
* @example SELECT FILE_ARCHIVER.PURGE_TRASH_FOLDER(pSourceFileReceivedKey => 12345) FROM DUAL;
|
||||||
|
* @ex_rslt 0 (success) or error code
|
||||||
|
**/
|
||||||
|
FUNCTION PURGE_TRASH_FOLDER (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pPurgeAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
-- PACKAGE VERSION MANAGEMENT FUNCTIONS
|
-- PACKAGE VERSION MANAGEMENT FUNCTIONS
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
2009
MARS_Packages/REL01_ADDITIONS/MARS-828/new_version/FILE_MANAGER.pkb
Normal file
2009
MARS_Packages/REL01_ADDITIONS/MARS-828/new_version/FILE_MANAGER.pkb
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,639 @@
|
|||||||
|
create or replace PACKAGE CT_MRDS.FILE_MANAGER
|
||||||
|
AUTHID CURRENT_USER
|
||||||
|
AS
|
||||||
|
/**
|
||||||
|
* General comment for package: Please put comments for functions and procedures as shown in below example.
|
||||||
|
* It is a standard.
|
||||||
|
* The structure of comment is used by GET_PACKAGE_DOCUMENTATION function
|
||||||
|
* which returns documentation text for confluence page (to Copy-Paste it).
|
||||||
|
**/
|
||||||
|
|
||||||
|
-- Example comment:
|
||||||
|
/**
|
||||||
|
* @name EX_PROCEDURE_NAME
|
||||||
|
* @desc Procedure description
|
||||||
|
* @example select FILE_MANAGER.EX_PROCEDURE_NAME(pParameter => 129) from dual;
|
||||||
|
* @ex_rslt Example Result
|
||||||
|
**/
|
||||||
|
|
||||||
|
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
||||||
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.5.1';
|
||||||
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-24 13:35:00';
|
||||||
|
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski';
|
||||||
|
|
||||||
|
-- Version History (Latest changes first)
|
||||||
|
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
||||||
|
'3.5.1 (2026-02-24): Fixed TIMESTAMP field syntax in GENERATE_EXTERNAL_TABLE_PARAMS for SQL*Loader compatibility (CHAR(35) DATE_FORMAT TIMESTAMP MASK format)' || CHR(13)||CHR(10) ||
|
||||||
|
'3.3.2 (2026-02-20): MARS-828 - Fixed threshold column names in GET_DET_SOURCE_FILE_CONFIG_INFO for MARS-828 compatibility' || CHR(13)||CHR(10) ||
|
||||||
|
'3.3.1 (2025-11-27): MARS-1046 - Fixed ISO 8601 datetime format parsing with milliseconds and timezone (e.g., 2012-03-02T14:16:23.798+01:00)' || CHR(13)||CHR(10) ||
|
||||||
|
'3.3.0 (2025-11-26): MARS-1056 - Fixed VARCHAR2 definitions in GENERATE_EXTERNAL_TABLE_PARAMS to preserve CHAR/BYTE semantics from template tables' || CHR(13)||CHR(10) ||
|
||||||
|
'3.2.1 (2025-11-24): MARS-1049 - Added pEncoding parameter support for CSV character set specification' || CHR(13)||CHR(10) ||
|
||||||
|
'3.2.0 (2025-10-22): Added package versioning system using centralized ENV_MANAGER functions' || CHR(13)||CHR(10) ||
|
||||||
|
'3.1.0 (2025-10-20): Enhanced PROCESS_SOURCE_FILE with 6-step validation workflow' || CHR(13)||CHR(10) ||
|
||||||
|
'3.0.0 (2025-10-15): Separated export procedures into dedicated DATA_EXPORTER package' || CHR(13)||CHR(10) ||
|
||||||
|
'2.5.0 (2025-10-10): Added DELETE_SOURCE_CASCADE for safe configuration removal' || CHR(13)||CHR(10) ||
|
||||||
|
'2.0.0 (2025-09-25): Added official path patterns support (INBOX 3-level, ODS 2-level, ARCHIVE 2-level)' || CHR(13)||CHR(10) ||
|
||||||
|
'1.0.0 (2025-09-01): Initial release with file processing and validation capabilities';
|
||||||
|
|
||||||
|
TYPE tSourceFileReceived IS RECORD
|
||||||
|
(
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE,
|
||||||
|
A_SOURCE_FILE_CONFIG_KEY CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_CONFIG_KEY%TYPE,
|
||||||
|
SOURCE_FILE_PREFIX_INBOX VARCHAR2(430),
|
||||||
|
SOURCE_FILE_PREFIX_ODS VARCHAR2(430),
|
||||||
|
SOURCE_FILE_PREFIX_QUARANTINE VARCHAR2(430),
|
||||||
|
SOURCE_FILE_PREFIX_ARCHIVE VARCHAR2(430),
|
||||||
|
SOURCE_FILE_NAME CT_MRDS.A_SOURCE_FILE_RECEIVED.SOURCE_FILE_NAME%TYPE,
|
||||||
|
RECEPTION_DATE CT_MRDS.A_SOURCE_FILE_RECEIVED.RECEPTION_DATE%TYPE,
|
||||||
|
PROCESSING_STATUS CT_MRDS.A_SOURCE_FILE_RECEIVED.PROCESSING_STATUS%TYPE,
|
||||||
|
EXTERNAL_TABLE_NAME CT_MRDS.A_SOURCE_FILE_RECEIVED.EXTERNAL_TABLE_NAME%TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
||||||
|
vgSourceFileConfigKey PLS_INTEGER;
|
||||||
|
vgMsgTmp VARCHAR2(32000);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_SOURCE_FILE_CONFIG
|
||||||
|
* @desc Get source file type by matching the source file name against source file type naming patterns
|
||||||
|
* or by specifying the id of a received source file.
|
||||||
|
* @example ...
|
||||||
|
* @ex_rslt "CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE"
|
||||||
|
**/
|
||||||
|
FUNCTION GET_SOURCE_FILE_CONFIG(pFileUri IN VARCHAR2 DEFAULT NULL
|
||||||
|
, pSourceFileReceivedKey IN NUMBER DEFAULT NULL
|
||||||
|
, pSourceFileConfigKey IN NUMBER DEFAULT NULL)
|
||||||
|
RETURN CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name REGISTER_SOURCE_FILE_RECEIVED
|
||||||
|
* @desc Register a newly received source file in A_SOURCE_FILE_RECEIVED table.
|
||||||
|
* This overload automatically determines source file type from the file name.
|
||||||
|
* It returns the value of A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY column for newly added record.
|
||||||
|
* @example vSourceFileReceivedKey := FILE_MANAGER.REGISTER_SOURCE_FILE_RECEIVED(pSourceFileReceivedName => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv');
|
||||||
|
* @ex_rslt 3245
|
||||||
|
**/
|
||||||
|
FUNCTION REGISTER_SOURCE_FILE_RECEIVED (
|
||||||
|
pSourceFileReceivedName IN VARCHAR2
|
||||||
|
)
|
||||||
|
RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name REGISTER_SOURCE_FILE_RECEIVED
|
||||||
|
* @desc Register a new new source file in A_SOURCE_FILE_RECEIVED table based on pSourceFileReceivedName and pSourceFileConfig.
|
||||||
|
* Then it returns the value of A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY column for newly added record.
|
||||||
|
* @example vSourceFileReceivedKey := FILE_MANAGER.REGISTER_SOURCE_FILE_RECEIVED(
|
||||||
|
* pSourceFileReceivedName => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv'
|
||||||
|
* ,pSourceFileConfig => ...A_SOURCE_FILE_CONFIG%ROWTYPE... );
|
||||||
|
* @ex_rslt 3245
|
||||||
|
**/
|
||||||
|
FUNCTION REGISTER_SOURCE_FILE_RECEIVED (
|
||||||
|
pSourceFileReceivedName IN VARCHAR2,
|
||||||
|
pSourceFileConfig IN CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE
|
||||||
|
)
|
||||||
|
RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name SET_SOURCE_FILE_RECEIVED_STATUS
|
||||||
|
* @desc Set status of file in A_SOURCE_FILE_RECEIVED table - PROCESSING_STATUS column
|
||||||
|
* based on A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY
|
||||||
|
* and provided value of pStatus parameter
|
||||||
|
* @example exec FILE_MANAGER.SET_SOURCE_FILE_RECEIVED_STATUS(pSourceFileReceivedKey => 377, pStatus => 'READY_FOR_INGESTION');
|
||||||
|
**/
|
||||||
|
PROCEDURE SET_SOURCE_FILE_RECEIVED_STATUS(
|
||||||
|
pSourceFileReceivedKey IN PLS_INTEGER,
|
||||||
|
pStatus IN VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_EXTERNAL_TABLE_COLUMNS
|
||||||
|
* @desc Function used to get string with all table columns definitions based on pTargetTableTemplate "TEMPLATE TABLE" name.
|
||||||
|
* It used for creating "EXTERNAL TABLE" using CREATE_EXTERNAL_TABLE procedure.
|
||||||
|
* @example select FILE_MANAGER.GET_EXTERNAL_TABLE_COLUMNS(pTargetTableTemplate => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER') from dual;
|
||||||
|
* @ex_rslt "A_KEY" NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
* "A_WORKFLOW_HISTORY_KEY" NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
* "REV_NUMBER" NUMBER(28,0),
|
||||||
|
* "REF_DATE" DATE,
|
||||||
|
* "FREE_TEXT" VARCHAR2(1000 CHAR),
|
||||||
|
* "MLF_BS_TOTAL" NUMBER(28,10),
|
||||||
|
* "DF_BS_TOTAL" NUMBER(28,10),
|
||||||
|
* "MLF_SF_TOTAL" NUMBER(28,10),
|
||||||
|
* "DF_SF_TOTAL" NUMBER(28,10)
|
||||||
|
**/
|
||||||
|
FUNCTION GET_EXTERNAL_TABLE_COLUMNS (
|
||||||
|
pTargetTableTemplate IN VARCHAR2
|
||||||
|
)
|
||||||
|
RETURN CLOB;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CREATE_EXTERNAL_TABLE
|
||||||
|
* @desc A wrapper procedure for DBMS_CLOUD.CREATE_EXTERNAL_TABLE which creates External Table
|
||||||
|
* MARS-1049: Added pEncoding parameter for CSV character set specification
|
||||||
|
* @param pEncoding - Character set encoding for CSV files (e.g., 'UTF8', 'WE8MSWIN1252')
|
||||||
|
* If provided, adds CHARACTERSET clause to external table definition
|
||||||
|
* @example
|
||||||
|
* begin
|
||||||
|
* FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
||||||
|
* pTableName => 'STANDING_FACILITIES_HEADER',
|
||||||
|
* pTemplateTableName => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER',
|
||||||
|
* pPrefix => 'ODS/LM/STANDING_FACILITIES_HEADER/',
|
||||||
|
* pBucketUri => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/frcnomajoc7v/b/mrds_data_tst/o/',
|
||||||
|
* pFileName => NULL,
|
||||||
|
* pDelimiter => ',',
|
||||||
|
* pEncoding => 'UTF8'
|
||||||
|
* );
|
||||||
|
* end;
|
||||||
|
**/
|
||||||
|
PROCEDURE CREATE_EXTERNAL_TABLE (
|
||||||
|
pTableName IN VARCHAR2,
|
||||||
|
pTemplateTableName IN VARCHAR2,
|
||||||
|
pPrefix IN VARCHAR2,
|
||||||
|
pBucketUri IN VARCHAR2 DEFAULT ENV_MANAGER.gvInboxBucketUri,
|
||||||
|
pFileName IN VARCHAR2 DEFAULT NULL,
|
||||||
|
pDelimiter IN VARCHAR2 DEFAULT ',',
|
||||||
|
pEncoding IN VARCHAR2 DEFAULT NULL -- MARS-1049: NOWY PARAMETR
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CREATE_EXTERNAL_TABLE
|
||||||
|
* @desc Creates External Table for single file provided by
|
||||||
|
* pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* @example exec FILE_MANAGER.CREATE_EXTERNAL_TABLE(pSourceFileReceivedKey => 377);;
|
||||||
|
**/
|
||||||
|
PROCEDURE CREATE_EXTERNAL_TABLE (
|
||||||
|
pSourceFileReceivedKey IN NUMBER
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name VALIDATE_SOURCE_FILE_RECEIVED
|
||||||
|
* @desc A wrapper procedure for DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE
|
||||||
|
* It validate External table build upon single file
|
||||||
|
* provided by pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* @example exec FILE_MANAGER.VALIDATE_SOURCE_FILE_RECEIVED(pSourceFileReceivedKey => 377);
|
||||||
|
**/
|
||||||
|
PROCEDURE VALIDATE_SOURCE_FILE_RECEIVED
|
||||||
|
(
|
||||||
|
pSourceFileReceivedKey IN NUMBER
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name VALIDATE_EXTERNAL_TABLE
|
||||||
|
* @desc A wrapper function for DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE.
|
||||||
|
* It validates External Table provided by parameter pTableName.
|
||||||
|
* It returns: PASSED or FAILED.
|
||||||
|
* @example
|
||||||
|
* declare
|
||||||
|
* vStatus VARCHAR2(100);
|
||||||
|
* begin
|
||||||
|
* vStatus := FILE_MANAGER.VALIDATE_EXTERNAL_TABLE(pTableName => 'STANDING_FACILITIES_HEADER');
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vStatus = '||vStatus);
|
||||||
|
* end;
|
||||||
|
*
|
||||||
|
* @ex_rslt FAILED
|
||||||
|
**/
|
||||||
|
FUNCTION VALIDATE_EXTERNAL_TABLE(pTableName IN VARCHAR2)
|
||||||
|
RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name S_VALIDATE_EXTERNAL_TABLE
|
||||||
|
* @desc A function which checks if SELECT query reterns any rows.
|
||||||
|
* It trys to selects External Table provided by parameter pTableName.
|
||||||
|
* It returns: PASSED or FAILED.
|
||||||
|
* @example
|
||||||
|
* declare
|
||||||
|
* vStatus VARCHAR2(100);
|
||||||
|
* begin
|
||||||
|
* vStatus := FILE_MANAGER.S_VALIDATE_EXTERNAL_TABLE(pTableName => 'STANDING_FACILITIES_HEADER');
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vStatus = '||vStatus);
|
||||||
|
* end;
|
||||||
|
*
|
||||||
|
* @ex_rslt PASSED
|
||||||
|
**/
|
||||||
|
FUNCTION S_VALIDATE_EXTERNAL_TABLE(pTableName IN VARCHAR2)
|
||||||
|
RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DROP_EXTERNAL_TABLE
|
||||||
|
* @desc It drops External Table for single file provided by
|
||||||
|
* pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* @example exec FILE_MANAGER.DROP_EXTERNAL_TABLE(pSourceFileReceivedKey => 377);
|
||||||
|
**/
|
||||||
|
PROCEDURE DROP_EXTERNAL_TABLE (
|
||||||
|
pSourceFileReceivedKey IN NUMBER
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name COPY_FILE
|
||||||
|
* @desc It copies file provided by
|
||||||
|
* pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* into destination provided by pDestination parameter.
|
||||||
|
* pDestination parameter allowed values are: 'ODS'
|
||||||
|
* @example exec FILE_MANAGER.COPY_FILE(pSourceFileReceivedKey => 377, pDestination => 'ODS');
|
||||||
|
**/
|
||||||
|
PROCEDURE COPY_FILE(
|
||||||
|
pSourceFileReceivedKey IN NUMBER,
|
||||||
|
pDestination IN VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name MOVE_FILE
|
||||||
|
* @desc It moves file provided by
|
||||||
|
* pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* into destination provided by pDestination parameter.
|
||||||
|
* pDestination parameter allowed values are: 'ODS', 'QUARANTINE'
|
||||||
|
* @example exec FILE_MANAGER.MOVE_FILE(pSourceFileReceivedKey => 377, pDestination => 'ODS');
|
||||||
|
**/
|
||||||
|
PROCEDURE MOVE_FILE(
|
||||||
|
pSourceFileReceivedKey IN NUMBER,
|
||||||
|
pDestination IN VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DELETE_FOLDER_CONTENTS
|
||||||
|
* @desc It deletes all files from specified folder in the cloud storage.
|
||||||
|
* The procedure lists all objects in the specified folder prefix and deletes them one by one.
|
||||||
|
* pBucketArea parameter specifies which bucket to use: 'INBOX', 'DATA', 'ARCHIVE'
|
||||||
|
* pFolderPrefix parameter specifies the folder path within the bucket (e.g., 'C2D/UC_DISSEM/UC_NMA_DISSEM/')
|
||||||
|
* @example exec FILE_MANAGER.DELETE_FOLDER_CONTENTS(pBucketArea => 'INBOX', pFolderPrefix => 'C2D/UC_DISSEM/UC_NMA_DISSEM/');
|
||||||
|
**/
|
||||||
|
PROCEDURE DELETE_FOLDER_CONTENTS(
|
||||||
|
pBucketArea IN VARCHAR2,
|
||||||
|
pFolderPrefix IN VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name PROCESS_SOURCE_FILE
|
||||||
|
* @desc It process file provided by pSourceFileReceivedName parameter.
|
||||||
|
* Ubmrella procedure that calls:
|
||||||
|
* - REGISTER_SOURCE_FILE_RECEIVED;
|
||||||
|
* - CREATE_EXTERNAL_TABLE;
|
||||||
|
* - VALIDATE_SOURCE_FILE_RECEIVED;
|
||||||
|
* - DROP_EXTERNAL_TABLE;
|
||||||
|
* - MOVE_FILE;
|
||||||
|
* @example exec FILE_MANAGER.PROCESS_SOURCE_FILE(pSourceFileReceivedName => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv');
|
||||||
|
**/
|
||||||
|
PROCEDURE PROCESS_SOURCE_FILE(pSourceFileReceivedName IN VARCHAR2)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name PROCESS_SOURCE_FILE
|
||||||
|
* @desc It process file provided by pSourceFileReceivedName parameter and return processing result value.
|
||||||
|
* It returns (success/failure) => 0 / -(value).
|
||||||
|
* Ubmrella function that calls PROCESS_SOURCE_FILE procedure.
|
||||||
|
* @example
|
||||||
|
* declare
|
||||||
|
* vResult PLS_INTEGER;
|
||||||
|
* begin
|
||||||
|
* vResult := CT_MRDS.FILE_MANAGER.PROCESS_SOURCE_FILE(PSOURCEFILERECEIVEDNAME => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv');
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vResult = ' || vResult);
|
||||||
|
* end;
|
||||||
|
* @ex_rslt 0
|
||||||
|
* -20021
|
||||||
|
**/
|
||||||
|
FUNCTION PROCESS_SOURCE_FILE(pSourceFileReceivedName IN VARCHAR2)
|
||||||
|
RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_DATE_FORMAT
|
||||||
|
* @desc Returns date format for specified template table name and column name.
|
||||||
|
* Date is taken from configuration A_COLUMN_DATE_FORMAT table.
|
||||||
|
* @example select FILE_MANAGER.GET_DATE_FORMAT(
|
||||||
|
* pTemplateTableName => 'STANDING_FACILITIES_HEADER',
|
||||||
|
* pColumnName => 'SNAPSHOT_DATE')
|
||||||
|
* from dual;
|
||||||
|
* @ex_rslt DD/MM/YYYY HH24:MI:SS
|
||||||
|
**/
|
||||||
|
FUNCTION GET_DATE_FORMAT(
|
||||||
|
pTemplateTableName IN VARCHAR2,
|
||||||
|
pColumnName IN VARCHAR2
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GENERATE_EXTERNAL_TABLE_PARAMS
|
||||||
|
* @desc It builds two strings: pColumnList and pFieldList for specified Template Table name, by parameter: pTemplateTableName.
|
||||||
|
* @example
|
||||||
|
* declare
|
||||||
|
* vColumnList CLOB;
|
||||||
|
* vFieldList CLOB;
|
||||||
|
* begin
|
||||||
|
* FILE_MANAGER.GENERATE_EXTERNAL_TABLE_PARAMS (
|
||||||
|
* pTemplateTableName => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER'
|
||||||
|
* ,pColumnList => vColumnList
|
||||||
|
* ,pFieldList => vFieldList
|
||||||
|
* );
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vColumnList = '||vColumnList);
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vFieldList = '||vFieldList);
|
||||||
|
* end;
|
||||||
|
* /
|
||||||
|
**/
|
||||||
|
PROCEDURE GENERATE_EXTERNAL_TABLE_PARAMS (
|
||||||
|
pTemplateTableName IN VARCHAR2,
|
||||||
|
pColumnList OUT CLOB,
|
||||||
|
pFieldList OUT CLOB
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ADD_SOURCE
|
||||||
|
* @desc Insert a new record to A_SOURCE table.
|
||||||
|
* pSourceKey is a PRIMARY KEY value.
|
||||||
|
**/
|
||||||
|
PROCEDURE ADD_SOURCE (
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE,
|
||||||
|
pSourceName IN CT_MRDS.A_SOURCE.SOURCE_NAME%TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DELETE_SOURCE_CASCADE
|
||||||
|
* @desc Safely deletes a SOURCE specified by pSourceKey parameter from A_SOURCE table and all dependent tables:
|
||||||
|
* - A_SOURCE_FILE_CONFIG
|
||||||
|
* - A_SOURCE_FILE_RECEIVED
|
||||||
|
* - A_COLUMN_DATE_FORMAT (only if template table is not shared with other source systems)
|
||||||
|
* The procedure checks if template tables are shared before deleting date format configurations.
|
||||||
|
* If a template table is used by multiple source systems, date formats are preserved.
|
||||||
|
* @example CALL CT_MRDS.FILE_MANAGER.DELETE_SOURCE_CASCADE(pSourceKey => 'TEST_SYS');
|
||||||
|
**/
|
||||||
|
PROCEDURE DELETE_SOURCE_CASCADE (
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_CONTAINER_SOURCE_FILE_CONFIG_KEY
|
||||||
|
* @desc For specified parameter pSourceFileId (A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID)
|
||||||
|
* it returns A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY for related CONTAINER record.
|
||||||
|
* @example select FILE_MANAGER.GET_CONTAINER_SOURCE_FILE_CONFIG_KEY(
|
||||||
|
* pSourceFileId => 'UC_DISSEM')
|
||||||
|
* from dual;
|
||||||
|
* @ex_rslt 126
|
||||||
|
**/
|
||||||
|
FUNCTION GET_CONTAINER_SOURCE_FILE_CONFIG_KEY (
|
||||||
|
pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_SOURCE_FILE_CONFIG_KEY
|
||||||
|
* @desc For specified input parameters,
|
||||||
|
* it returns A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY.
|
||||||
|
* @example select FILE_MANAGER.GET_SOURCE_FILE_CONFIG_KEY (
|
||||||
|
* pSourceFileType => 'INPUT'
|
||||||
|
* ,pSourceFileId => 'UC_DISSEM'
|
||||||
|
* ,pTableId => 'UC_NMA_DISSEM')
|
||||||
|
* from dual;
|
||||||
|
* @ex_rslt 126
|
||||||
|
**/
|
||||||
|
FUNCTION GET_SOURCE_FILE_CONFIG_KEY (
|
||||||
|
pSourceFileType IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE%TYPE DEFAULT 'INPUT'
|
||||||
|
,pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE
|
||||||
|
,pTableId IN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID%TYPE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ADD_SOURCE_FILE_CONFIG
|
||||||
|
* @desc Insert a new record to A_SOURCE_FILE_CONFIG table.
|
||||||
|
* MARS-1049: Added pEncoding parameter for CSV character set specification.
|
||||||
|
* @param pEncoding - Character set encoding for CSV files (e.g., 'UTF8', 'WE8MSWIN1252', 'EE8ISO8859P2')
|
||||||
|
* If NULL, no CHARACTERSET clause is added to external table definitions
|
||||||
|
* @example CALL CT_MRDS.FILE_MANAGER.ADD_SOURCE_FILE_CONFIG(
|
||||||
|
* pSourceKey => 'C2D', pSourceFileType => 'INPUT',
|
||||||
|
* pSourceFileId => 'UC_DISSEM', pTableId => 'METADATA_LOADS',
|
||||||
|
* pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
||||||
|
* pEncoding => 'UTF8'
|
||||||
|
* );
|
||||||
|
**/
|
||||||
|
PROCEDURE ADD_SOURCE_FILE_CONFIG (
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_KEY%TYPE
|
||||||
|
,pSourceFileType IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE%TYPE
|
||||||
|
,pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE
|
||||||
|
,pSourceFileDesc IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_DESC%TYPE
|
||||||
|
,pSourceFileNamePattern IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_NAME_PATTERN%TYPE
|
||||||
|
,pTableId IN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID%TYPE DEFAULT NULL
|
||||||
|
,pTemplateTableName IN CT_MRDS.A_SOURCE_FILE_CONFIG.TEMPLATE_TABLE_NAME%TYPE DEFAULT NULL
|
||||||
|
,pContainerFileKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.CONTAINER_FILE_KEY%TYPE DEFAULT NULL
|
||||||
|
,pEncoding IN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING%TYPE DEFAULT NULL -- MARS-1049: NOWY PARAMETR
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ADD_COLUMN_DATE_FORMAT
|
||||||
|
* @desc Insert a new record to A_COLUMN_DATE_FORMAT table.
|
||||||
|
**/
|
||||||
|
PROCEDURE ADD_COLUMN_DATE_FORMAT (
|
||||||
|
pTemplateTableName IN CT_MRDS.A_COLUMN_DATE_FORMAT.TEMPLATE_TABLE_NAME%TYPE
|
||||||
|
,pColumnName IN CT_MRDS.A_COLUMN_DATE_FORMAT.COLUMN_NAME%TYPE
|
||||||
|
,pDateFormat IN CT_MRDS.A_COLUMN_DATE_FORMAT.DATE_FORMAT%TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_BUCKET_URI
|
||||||
|
* @desc Function used to get string with bucket http url.
|
||||||
|
* Possible input values for pBucketArea are: 'INBOX', 'ODS', 'DATA', 'ARCHIVE'
|
||||||
|
* @example select FILE_MANAGER.GET_BUCKET_URI(pBucketArea => 'ODS') from dual;
|
||||||
|
* @ex_rslt https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/frcnomajoc7v/b/mrds_data_tst/o/
|
||||||
|
**/
|
||||||
|
FUNCTION GET_BUCKET_URI(pBucketArea VARCHAR2)
|
||||||
|
RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_DET_SOURCE_FILE_CONFIG_INFO
|
||||||
|
* @desc Function returns details about A_SOURCE_FILE_CONFIG record
|
||||||
|
* for specified pSourceFileConfigKey (A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY).
|
||||||
|
* If pIncludeContainerInfo is <> 0 it returns additional info about related Container config record (A_SOURCE_FILE_CONFIG)
|
||||||
|
* If pIncludeColumnFormatInfo is <> 0 it returns additional info about related ColumnFormat config record (A_COLUMN_DATE_FORMAT)
|
||||||
|
* @example select FILE_MANAGER.GET_DET_SOURCE_FILE_CONFIG_INFO (
|
||||||
|
* pSourceFileConfigKey => 128
|
||||||
|
* ,pIncludeContainerInfo => 1
|
||||||
|
* ,pIncludeColumnFormatInfo => 1
|
||||||
|
* ) from dual;
|
||||||
|
* @ex_rslt
|
||||||
|
* Details about File Configuration:
|
||||||
|
* --------------------------------
|
||||||
|
* A_SOURCE_FILE_CONFIG_KEY = 128
|
||||||
|
* A_SOURCE_KEY = C2D
|
||||||
|
* ...
|
||||||
|
* --------------------------------
|
||||||
|
*
|
||||||
|
* Details about related Container Config:
|
||||||
|
* --------------------------------
|
||||||
|
* A_SOURCE_FILE_CONFIG_KEY = 126
|
||||||
|
* A_SOURCE_KEY = C2D
|
||||||
|
* ...
|
||||||
|
* --------------------------------
|
||||||
|
*
|
||||||
|
* Column Date Format config entries:
|
||||||
|
* --------------------------------
|
||||||
|
* TEMPLATE_TABLE_NAME = CT_ET_TEMPLATES.C2D_UC_MA_DISSEM
|
||||||
|
* ...
|
||||||
|
* --------------------------------
|
||||||
|
**/
|
||||||
|
FUNCTION GET_DET_SOURCE_FILE_CONFIG_INFO (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
||||||
|
,pIncludeContainerInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
,pIncludeColumnFormatInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_DET_SOURCE_FILE_RECEIVED_INFO
|
||||||
|
* @desc Function returns details about A_SOURCE_FILE_RECEIVED record
|
||||||
|
* for specified pSourceFileReceivedKey (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY).
|
||||||
|
* If pIncludeConfigInfo is <> 0 it returns additional info about related Container config record (A_SOURCE_FILE_CONFIG)
|
||||||
|
* If pIncludeContainerInfo is <> 0 it returns additional info about related Container config record (A_SOURCE_FILE_CONFIG)
|
||||||
|
* If pIncludeColumnFormatInfo is <> 0 it returns additional info about related ColumnFormat config record (A_COLUMN_DATE_FORMAT)
|
||||||
|
* @example select FILE_MANAGER.GET_DET_SOURCE_FILE_RECEIVED_INFO (
|
||||||
|
* pSourceFileReceivedKey => 377
|
||||||
|
* ,pIncludeConfigInfo => 1
|
||||||
|
* ,pIncludeContainerInfo => 1
|
||||||
|
* ,pIncludeColumnFormatInfo => 1
|
||||||
|
* ) from dual;
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
FUNCTION GET_DET_SOURCE_FILE_RECEIVED_INFO (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE
|
||||||
|
,pIncludeConfigInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
,pIncludeContainerInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
,pIncludeColumnFormatInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_DET_USER_LOAD_OPERATIONS
|
||||||
|
* @desc Function returns details from USER_LOAD_OPERATIONS table
|
||||||
|
* for specified pOperationId.
|
||||||
|
* @example select FILE_MANAGER.GET_DET_USER_LOAD_OPERATIONS (pOperationId => 3608) from dual;
|
||||||
|
* @ex_rslt
|
||||||
|
* Details about USER_LOAD_OPERATIONS where ID = 3608
|
||||||
|
* --------------------------------
|
||||||
|
* ID = 3608
|
||||||
|
* TYPE = VALIDATE
|
||||||
|
* SID = 31260
|
||||||
|
* SERIAL# = 52915
|
||||||
|
* START_TIME = 2025-05-20 10.08.24.436983 EUROPE/BELGRADE
|
||||||
|
* UPDATE_TIME = 2025-05-20 10.08.24.458643 EUROPE/BELGRADE
|
||||||
|
* STATUS = FAILED
|
||||||
|
* OWNER_NAME = CT_MRDS
|
||||||
|
* TABLE_NAME = STANDING_FACILITIES_HEADER
|
||||||
|
* PARTITION_NAME =
|
||||||
|
* SUBPARTITION_NAME =
|
||||||
|
* FILE_URI_LIST =
|
||||||
|
* ROWS_LOADED =
|
||||||
|
* LOGFILE_TABLE = VALIDATE$3608_LOG
|
||||||
|
* BADFILE_TABLE = VALIDATE$3608_BAD
|
||||||
|
* STATUS_TABLE =
|
||||||
|
* TEMPEXT_TABLE =
|
||||||
|
* CREDENTIAL_NAME =
|
||||||
|
* EXPIRATION_TIME = 2025-05-22 10.08.24.436983000 EUROPE/BELGRADE
|
||||||
|
* --------------------------------
|
||||||
|
**/
|
||||||
|
FUNCTION GET_DET_USER_LOAD_OPERATIONS (
|
||||||
|
pOperationId PLS_INTEGER
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ANALYZE_VALIDATION_ERRORS
|
||||||
|
* @desc Wrapper function that analyzes validation errors for a source file using its received key.
|
||||||
|
* Automatically derives template schema, table name, CSV URI and validation log table
|
||||||
|
* from file metadata and calls ENV_MANAGER.ANALYZE_VALIDATION_ERRORS.
|
||||||
|
* @example SELECT FILE_MANAGER.ANALYZE_VALIDATION_ERRORS(63) FROM DUAL;
|
||||||
|
* @ex_rslt Detailed validation analysis report with column mismatches and solutions
|
||||||
|
**/
|
||||||
|
FUNCTION ANALYZE_VALIDATION_ERRORS(
|
||||||
|
pSourceFileReceivedKey IN NUMBER
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- PACKAGE VERSION MANAGEMENT FUNCTIONS
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_VERSION
|
||||||
|
* @desc Returns the current version number of the FILE_MANAGER package.
|
||||||
|
* Uses semantic versioning format (MAJOR.MINOR.PATCH).
|
||||||
|
* @example SELECT FILE_MANAGER.GET_VERSION() FROM DUAL;
|
||||||
|
* @ex_rslt 3.2.0
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_BUILD_INFO
|
||||||
|
* @desc Returns comprehensive build information including version, build date, and author.
|
||||||
|
* Uses centralized ENV_MANAGER.GET_PACKAGE_VERSION_INFO function.
|
||||||
|
* @example SELECT FILE_MANAGER.GET_BUILD_INFO() FROM DUAL;
|
||||||
|
* @ex_rslt Package: FILE_MANAGER
|
||||||
|
* Version: 3.2.0
|
||||||
|
* Build Date: 2025-10-22 16:30:00
|
||||||
|
* Author: Grzegorz Michalski
|
||||||
|
**/
|
||||||
|
FUNCTION GET_BUILD_INFO RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_VERSION_HISTORY
|
||||||
|
* @desc Returns complete version history with all releases and changes.
|
||||||
|
* Uses centralized ENV_MANAGER.FORMAT_VERSION_HISTORY function.
|
||||||
|
* @example SELECT FILE_MANAGER.GET_VERSION_HISTORY() FROM DUAL;
|
||||||
|
* @ex_rslt FILE_MANAGER Version History:
|
||||||
|
* 3.2.0 (2025-10-22): Added package versioning system...
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2;
|
||||||
|
|
||||||
|
END;
|
||||||
|
|
||||||
|
/
|
||||||
|
|
||||||
|
/
|
||||||
@@ -20,10 +20,10 @@ BEGIN
|
|||||||
RAISE_APPLICATION_ERROR(-20999, vErrorMsg);
|
RAISE_APPLICATION_ERROR(-20999, vErrorMsg);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Validate MINIMUM_AGE_MONTHS is positive
|
-- Validate MINIMUM_AGE_MONTHS is non-negative (0 = current month only)
|
||||||
IF :NEW.MINIMUM_AGE_MONTHS IS NOT NULL
|
IF :NEW.MINIMUM_AGE_MONTHS IS NOT NULL
|
||||||
AND :NEW.MINIMUM_AGE_MONTHS < 1 THEN
|
AND :NEW.MINIMUM_AGE_MONTHS < 0 THEN
|
||||||
RAISE_APPLICATION_ERROR(-20998, 'MINIMUM_AGE_MONTHS must be greater than 0');
|
RAISE_APPLICATION_ERROR(-20998, 'MINIMUM_AGE_MONTHS must be greater than or equal to 0');
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Warn if MINIMUM_AGE_MONTHS set but strategy doesn't use it
|
-- Warn if MINIMUM_AGE_MONTHS set but strategy doesn't use it
|
||||||
|
|||||||
@@ -29,13 +29,18 @@ PROMPT
|
|||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
PROMPT MARS-828 Rollback Starting
|
PROMPT MARS-828 Rollback Starting
|
||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
PROMPT WARNING: This will restore FILE_ARCHIVER to v2.0.0
|
PROMPT This will restore FILE_ARCHIVER to v2.0.0
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT CRITICAL IMPACT:
|
PROMPT Rollback steps:
|
||||||
PROMPT 1. All archival strategies revert to THRESHOLD_BASED
|
PROMPT 1. Rollback TRASH retention statuses
|
||||||
PROMPT 2. ARCHIVAL_STRATEGY and MINIMUM_AGE_MONTHS columns will be dropped
|
PROMPT 2. Revoke T_FILENAME privileges
|
||||||
PROMPT 3. Validation trigger will be removed
|
PROMPT 3. Remove validation trigger
|
||||||
PROMPT 4. Reconfigure archival thresholds after rollback
|
PROMPT 4. Remove column comments (OPTIONAL - does not affect functionality)
|
||||||
|
PROMPT 5. Revert threshold column renames (restore original naming)
|
||||||
|
PROMPT 6. Drop all configuration columns (ARCHIVAL_STRATEGY, MINIMUM_AGE_MONTHS, IS_ARCHIVE_ENABLED, IS_KEEP_IN_TRASH)
|
||||||
|
PROMPT 7. Restore FILE_ARCHIVER package to v2.0.0
|
||||||
|
PROMPT 8. Restore FILE_MANAGER package to v3.3.1
|
||||||
|
PROMPT 9. Revert all archival strategies to THRESHOLD_BASED
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Timestamp:
|
PROMPT Timestamp:
|
||||||
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS rollback_start FROM DUAL;
|
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS rollback_start FROM DUAL;
|
||||||
@@ -54,33 +59,61 @@ WHENEVER SQLERROR CONTINUE
|
|||||||
|
|
||||||
-- Rollback steps (in reverse order)
|
-- Rollback steps (in reverse order)
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 1/6: Restoring FILE_ARCHIVER Package Specification v2.0.0
|
PROMPT Step 1/9: Rolling back TRASH retention statuses
|
||||||
PROMPT ===============================================================
|
PROMPT ================================================
|
||||||
@@91_MARS_828_rollback_FILE_ARCHIVER_SPEC.sql
|
@@90_MARS_828_rollback_trash_retention_statuses.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 2/6: Restoring FILE_ARCHIVER Package Body v2.0.0
|
PROMPT Step 2/9: Revoking T_FILENAME privileges from MRDS_LOADER
|
||||||
PROMPT ======================================================
|
PROMPT ==========================================================
|
||||||
@@92_MARS_828_rollback_FILE_ARCHIVER_BODY.sql
|
@@95_MARS_828_rollback_grant_t_filename.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 3/6: Dropping validation trigger
|
PROMPT Step 3/9: Dropping validation trigger
|
||||||
PROMPT ======================================
|
PROMPT ======================================
|
||||||
@@93_MARS_828_rollback_trigger.sql
|
@@93_MARS_828_rollback_trigger.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 4/6: Dropping archival strategy columns
|
PROMPT Step 4/9 (OPTIONAL): Removing column comments
|
||||||
|
PROMPT ==============================================
|
||||||
|
PROMPT NOTE: This is optional - comments do not affect functionality
|
||||||
|
PROMPT Skipping column comments removal in standard rollback
|
||||||
|
PROMPT Execute 94b_MARS_828_rollback_column_comments.sql manually if needed
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 5/9: Reverting threshold column renames
|
||||||
PROMPT =============================================
|
PROMPT =============================================
|
||||||
|
@@94a_MARS_828_rollback_threshold_rename.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 6/9: Dropping all archival configuration columns
|
||||||
|
PROMPT ======================================================
|
||||||
@@94_MARS_828_rollback_columns.sql
|
@@94_MARS_828_rollback_columns.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 5/6: Tracking rollback version
|
PROMPT Step 7/9: Restoring FILE_ARCHIVER Package Specification v2.0.0
|
||||||
PROMPT ====================================
|
PROMPT ===============================================================
|
||||||
@@track_package_versions.sql
|
@@91_MARS_828_rollback_FILE_ARCHIVER_SPEC.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 6/6: Verifying tracked packages
|
PROMPT Step 8/11: Restoring FILE_ARCHIVER Package Body v2.0.0
|
||||||
PROMPT =====================================
|
PROMPT =======================================================
|
||||||
|
@@92_MARS_828_rollback_FILE_ARCHIVER_BODY.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 9/11: Restoring FILE_MANAGER Package Specification v3.3.1
|
||||||
|
PROMPT ===============================================================
|
||||||
|
@@97_MARS_828_rollback_FILE_MANAGER_SPEC.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 10/11: Restoring FILE_MANAGER Package Body v3.3.1
|
||||||
|
PROMPT ======================================================
|
||||||
|
@@98_MARS_828_rollback_FILE_MANAGER_BODY.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 11/11: Verifying tracked packages
|
||||||
|
PROMPT ======================================
|
||||||
@@verify_packages_version.sql
|
@@verify_packages_version.sql
|
||||||
|
|
||||||
-- Verify rollback
|
-- Verify rollback
|
||||||
@@ -90,9 +123,9 @@ PROMPT =========================================
|
|||||||
SELECT object_name, object_type, status, last_ddl_time
|
SELECT object_name, object_type, status, last_ddl_time
|
||||||
FROM all_objects
|
FROM all_objects
|
||||||
WHERE owner = 'CT_MRDS'
|
WHERE owner = 'CT_MRDS'
|
||||||
AND object_name = 'FILE_ARCHIVER'
|
AND object_name IN ('FILE_ARCHIVER', 'FILE_MANAGER')
|
||||||
AND object_type IN ('PACKAGE', 'PACKAGE BODY')
|
AND object_type IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
ORDER BY object_type;
|
ORDER BY object_name, object_type;
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
@@ -102,8 +135,9 @@ PROMPT Completion Time:
|
|||||||
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS rollback_end FROM DUAL;
|
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS rollback_end FROM DUAL;
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Rollback Summary:
|
PROMPT Rollback Summary:
|
||||||
PROMPT - Package: CT_MRDS.FILE_ARCHIVER
|
PROMPT - Packages Rolled Back:
|
||||||
PROMPT - Restored Version: 2.0.0 (THRESHOLD_BASED archival only)
|
PROMPT * CT_MRDS.FILE_ARCHIVER to v2.0.0 (THRESHOLD_BASED archival only)
|
||||||
|
PROMPT * CT_MRDS.FILE_MANAGER to v3.3.1 (pre-MARS-828 threshold column compatibility)
|
||||||
PROMPT - Removed Features: CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID strategies
|
PROMPT - Removed Features: CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID strategies
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Log file: &_filename
|
PROMPT Log file: &_filename
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,637 @@
|
|||||||
|
create or replace PACKAGE CT_MRDS.FILE_MANAGER
|
||||||
|
AUTHID CURRENT_USER
|
||||||
|
AS
|
||||||
|
/**
|
||||||
|
* General comment for package: Please put comments for functions and procedures as shown in below example.
|
||||||
|
* It is a standard.
|
||||||
|
* The structure of comment is used by GET_PACKAGE_DOCUMENTATION function
|
||||||
|
* which returns documentation text for confluence page (to Copy-Paste it).
|
||||||
|
**/
|
||||||
|
|
||||||
|
-- Example comment:
|
||||||
|
/**
|
||||||
|
* @name EX_PROCEDURE_NAME
|
||||||
|
* @desc Procedure description
|
||||||
|
* @example select FILE_MANAGER.EX_PROCEDURE_NAME(pParameter => 129) from dual;
|
||||||
|
* @ex_rslt Example Result
|
||||||
|
**/
|
||||||
|
|
||||||
|
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
||||||
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.3.1';
|
||||||
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-11-27 14:00:00';
|
||||||
|
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski';
|
||||||
|
|
||||||
|
-- Version History (Latest changes first)
|
||||||
|
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
||||||
|
'3.3.1 (2025-11-27): MARS-1046 - Fixed ISO 8601 datetime format parsing with milliseconds and timezone (e.g., 2012-03-02T14:16:23.798+01:00)' || CHR(13)||CHR(10) ||
|
||||||
|
'3.3.0 (2025-11-26): MARS-1056 - Fixed VARCHAR2 definitions in GENERATE_EXTERNAL_TABLE_PARAMS to preserve CHAR/BYTE semantics from template tables' || CHR(13)||CHR(10) ||
|
||||||
|
'3.2.1 (2025-11-24): MARS-1049 - Added pEncoding parameter support for CSV character set specification' || CHR(13)||CHR(10) ||
|
||||||
|
'3.2.0 (2025-10-22): Added package versioning system using centralized ENV_MANAGER functions' || CHR(13)||CHR(10) ||
|
||||||
|
'3.1.0 (2025-10-20): Enhanced PROCESS_SOURCE_FILE with 6-step validation workflow' || CHR(13)||CHR(10) ||
|
||||||
|
'3.0.0 (2025-10-15): Separated export procedures into dedicated DATA_EXPORTER package' || CHR(13)||CHR(10) ||
|
||||||
|
'2.5.0 (2025-10-10): Added DELETE_SOURCE_CASCADE for safe configuration removal' || CHR(13)||CHR(10) ||
|
||||||
|
'2.0.0 (2025-09-25): Added official path patterns support (INBOX 3-level, ODS 2-level, ARCHIVE 2-level)' || CHR(13)||CHR(10) ||
|
||||||
|
'1.0.0 (2025-09-01): Initial release with file processing and validation capabilities';
|
||||||
|
|
||||||
|
TYPE tSourceFileReceived IS RECORD
|
||||||
|
(
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE,
|
||||||
|
A_SOURCE_FILE_CONFIG_KEY CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_CONFIG_KEY%TYPE,
|
||||||
|
SOURCE_FILE_PREFIX_INBOX VARCHAR2(430),
|
||||||
|
SOURCE_FILE_PREFIX_ODS VARCHAR2(430),
|
||||||
|
SOURCE_FILE_PREFIX_QUARANTINE VARCHAR2(430),
|
||||||
|
SOURCE_FILE_PREFIX_ARCHIVE VARCHAR2(430),
|
||||||
|
SOURCE_FILE_NAME CT_MRDS.A_SOURCE_FILE_RECEIVED.SOURCE_FILE_NAME%TYPE,
|
||||||
|
RECEPTION_DATE CT_MRDS.A_SOURCE_FILE_RECEIVED.RECEPTION_DATE%TYPE,
|
||||||
|
PROCESSING_STATUS CT_MRDS.A_SOURCE_FILE_RECEIVED.PROCESSING_STATUS%TYPE,
|
||||||
|
EXTERNAL_TABLE_NAME CT_MRDS.A_SOURCE_FILE_RECEIVED.EXTERNAL_TABLE_NAME%TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
||||||
|
vgSourceFileConfigKey PLS_INTEGER;
|
||||||
|
vgMsgTmp VARCHAR2(32000);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_SOURCE_FILE_CONFIG
|
||||||
|
* @desc Get source file type by matching the source file name against source file type naming patterns
|
||||||
|
* or by specifying the id of a received source file.
|
||||||
|
* @example ...
|
||||||
|
* @ex_rslt "CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE"
|
||||||
|
**/
|
||||||
|
FUNCTION GET_SOURCE_FILE_CONFIG(pFileUri IN VARCHAR2 DEFAULT NULL
|
||||||
|
, pSourceFileReceivedKey IN NUMBER DEFAULT NULL
|
||||||
|
, pSourceFileConfigKey IN NUMBER DEFAULT NULL)
|
||||||
|
RETURN CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name REGISTER_SOURCE_FILE_RECEIVED
|
||||||
|
* @desc Register a newly received source file in A_SOURCE_FILE_RECEIVED table.
|
||||||
|
* This overload automatically determines source file type from the file name.
|
||||||
|
* It returns the value of A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY column for newly added record.
|
||||||
|
* @example vSourceFileReceivedKey := FILE_MANAGER.REGISTER_SOURCE_FILE_RECEIVED(pSourceFileReceivedName => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv');
|
||||||
|
* @ex_rslt 3245
|
||||||
|
**/
|
||||||
|
FUNCTION REGISTER_SOURCE_FILE_RECEIVED (
|
||||||
|
pSourceFileReceivedName IN VARCHAR2
|
||||||
|
)
|
||||||
|
RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name REGISTER_SOURCE_FILE_RECEIVED
|
||||||
|
* @desc Register a new new source file in A_SOURCE_FILE_RECEIVED table based on pSourceFileReceivedName and pSourceFileConfig.
|
||||||
|
* Then it returns the value of A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY column for newly added record.
|
||||||
|
* @example vSourceFileReceivedKey := FILE_MANAGER.REGISTER_SOURCE_FILE_RECEIVED(
|
||||||
|
* pSourceFileReceivedName => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv'
|
||||||
|
* ,pSourceFileConfig => ...A_SOURCE_FILE_CONFIG%ROWTYPE... );
|
||||||
|
* @ex_rslt 3245
|
||||||
|
**/
|
||||||
|
FUNCTION REGISTER_SOURCE_FILE_RECEIVED (
|
||||||
|
pSourceFileReceivedName IN VARCHAR2,
|
||||||
|
pSourceFileConfig IN CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE
|
||||||
|
)
|
||||||
|
RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name SET_SOURCE_FILE_RECEIVED_STATUS
|
||||||
|
* @desc Set status of file in A_SOURCE_FILE_RECEIVED table - PROCESSING_STATUS column
|
||||||
|
* based on A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY
|
||||||
|
* and provided value of pStatus parameter
|
||||||
|
* @example exec FILE_MANAGER.SET_SOURCE_FILE_RECEIVED_STATUS(pSourceFileReceivedKey => 377, pStatus => 'READY_FOR_INGESTION');
|
||||||
|
**/
|
||||||
|
PROCEDURE SET_SOURCE_FILE_RECEIVED_STATUS(
|
||||||
|
pSourceFileReceivedKey IN PLS_INTEGER,
|
||||||
|
pStatus IN VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_EXTERNAL_TABLE_COLUMNS
|
||||||
|
* @desc Function used to get string with all table columns definitions based on pTargetTableTemplate "TEMPLATE TABLE" name.
|
||||||
|
* It used for creating "EXTERNAL TABLE" using CREATE_EXTERNAL_TABLE procedure.
|
||||||
|
* @example select FILE_MANAGER.GET_EXTERNAL_TABLE_COLUMNS(pTargetTableTemplate => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER') from dual;
|
||||||
|
* @ex_rslt "A_KEY" NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
* "A_WORKFLOW_HISTORY_KEY" NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
* "REV_NUMBER" NUMBER(28,0),
|
||||||
|
* "REF_DATE" DATE,
|
||||||
|
* "FREE_TEXT" VARCHAR2(1000 CHAR),
|
||||||
|
* "MLF_BS_TOTAL" NUMBER(28,10),
|
||||||
|
* "DF_BS_TOTAL" NUMBER(28,10),
|
||||||
|
* "MLF_SF_TOTAL" NUMBER(28,10),
|
||||||
|
* "DF_SF_TOTAL" NUMBER(28,10)
|
||||||
|
**/
|
||||||
|
FUNCTION GET_EXTERNAL_TABLE_COLUMNS (
|
||||||
|
pTargetTableTemplate IN VARCHAR2
|
||||||
|
)
|
||||||
|
RETURN CLOB;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CREATE_EXTERNAL_TABLE
|
||||||
|
* @desc A wrapper procedure for DBMS_CLOUD.CREATE_EXTERNAL_TABLE which creates External Table
|
||||||
|
* MARS-1049: Added pEncoding parameter for CSV character set specification
|
||||||
|
* @param pEncoding - Character set encoding for CSV files (e.g., 'UTF8', 'WE8MSWIN1252')
|
||||||
|
* If provided, adds CHARACTERSET clause to external table definition
|
||||||
|
* @example
|
||||||
|
* begin
|
||||||
|
* FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
||||||
|
* pTableName => 'STANDING_FACILITIES_HEADER',
|
||||||
|
* pTemplateTableName => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER',
|
||||||
|
* pPrefix => 'ODS/LM/STANDING_FACILITIES_HEADER/',
|
||||||
|
* pBucketUri => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/frcnomajoc7v/b/mrds_data_tst/o/',
|
||||||
|
* pFileName => NULL,
|
||||||
|
* pDelimiter => ',',
|
||||||
|
* pEncoding => 'UTF8'
|
||||||
|
* );
|
||||||
|
* end;
|
||||||
|
**/
|
||||||
|
PROCEDURE CREATE_EXTERNAL_TABLE (
|
||||||
|
pTableName IN VARCHAR2,
|
||||||
|
pTemplateTableName IN VARCHAR2,
|
||||||
|
pPrefix IN VARCHAR2,
|
||||||
|
pBucketUri IN VARCHAR2 DEFAULT ENV_MANAGER.gvInboxBucketUri,
|
||||||
|
pFileName IN VARCHAR2 DEFAULT NULL,
|
||||||
|
pDelimiter IN VARCHAR2 DEFAULT ',',
|
||||||
|
pEncoding IN VARCHAR2 DEFAULT NULL -- MARS-1049: NOWY PARAMETR
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CREATE_EXTERNAL_TABLE
|
||||||
|
* @desc Creates External Table for single file provided by
|
||||||
|
* pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* @example exec FILE_MANAGER.CREATE_EXTERNAL_TABLE(pSourceFileReceivedKey => 377);;
|
||||||
|
**/
|
||||||
|
PROCEDURE CREATE_EXTERNAL_TABLE (
|
||||||
|
pSourceFileReceivedKey IN NUMBER
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name VALIDATE_SOURCE_FILE_RECEIVED
|
||||||
|
* @desc A wrapper procedure for DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE
|
||||||
|
* It validate External table build upon single file
|
||||||
|
* provided by pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* @example exec FILE_MANAGER.VALIDATE_SOURCE_FILE_RECEIVED(pSourceFileReceivedKey => 377);
|
||||||
|
**/
|
||||||
|
PROCEDURE VALIDATE_SOURCE_FILE_RECEIVED
|
||||||
|
(
|
||||||
|
pSourceFileReceivedKey IN NUMBER
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name VALIDATE_EXTERNAL_TABLE
|
||||||
|
* @desc A wrapper function for DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE.
|
||||||
|
* It validates External Table provided by parameter pTableName.
|
||||||
|
* It returns: PASSED or FAILED.
|
||||||
|
* @example
|
||||||
|
* declare
|
||||||
|
* vStatus VARCHAR2(100);
|
||||||
|
* begin
|
||||||
|
* vStatus := FILE_MANAGER.VALIDATE_EXTERNAL_TABLE(pTableName => 'STANDING_FACILITIES_HEADER');
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vStatus = '||vStatus);
|
||||||
|
* end;
|
||||||
|
*
|
||||||
|
* @ex_rslt FAILED
|
||||||
|
**/
|
||||||
|
FUNCTION VALIDATE_EXTERNAL_TABLE(pTableName IN VARCHAR2)
|
||||||
|
RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name S_VALIDATE_EXTERNAL_TABLE
|
||||||
|
* @desc A function which checks if SELECT query reterns any rows.
|
||||||
|
* It trys to selects External Table provided by parameter pTableName.
|
||||||
|
* It returns: PASSED or FAILED.
|
||||||
|
* @example
|
||||||
|
* declare
|
||||||
|
* vStatus VARCHAR2(100);
|
||||||
|
* begin
|
||||||
|
* vStatus := FILE_MANAGER.S_VALIDATE_EXTERNAL_TABLE(pTableName => 'STANDING_FACILITIES_HEADER');
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vStatus = '||vStatus);
|
||||||
|
* end;
|
||||||
|
*
|
||||||
|
* @ex_rslt PASSED
|
||||||
|
**/
|
||||||
|
FUNCTION S_VALIDATE_EXTERNAL_TABLE(pTableName IN VARCHAR2)
|
||||||
|
RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DROP_EXTERNAL_TABLE
|
||||||
|
* @desc It drops External Table for single file provided by
|
||||||
|
* pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* @example exec FILE_MANAGER.DROP_EXTERNAL_TABLE(pSourceFileReceivedKey => 377);
|
||||||
|
**/
|
||||||
|
PROCEDURE DROP_EXTERNAL_TABLE (
|
||||||
|
pSourceFileReceivedKey IN NUMBER
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name COPY_FILE
|
||||||
|
* @desc It copies file provided by
|
||||||
|
* pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* into destination provided by pDestination parameter.
|
||||||
|
* pDestination parameter allowed values are: 'ODS'
|
||||||
|
* @example exec FILE_MANAGER.COPY_FILE(pSourceFileReceivedKey => 377, pDestination => 'ODS');
|
||||||
|
**/
|
||||||
|
PROCEDURE COPY_FILE(
|
||||||
|
pSourceFileReceivedKey IN NUMBER,
|
||||||
|
pDestination IN VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name MOVE_FILE
|
||||||
|
* @desc It moves file provided by
|
||||||
|
* pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY)
|
||||||
|
* into destination provided by pDestination parameter.
|
||||||
|
* pDestination parameter allowed values are: 'ODS', 'QUARANTINE'
|
||||||
|
* @example exec FILE_MANAGER.MOVE_FILE(pSourceFileReceivedKey => 377, pDestination => 'ODS');
|
||||||
|
**/
|
||||||
|
PROCEDURE MOVE_FILE(
|
||||||
|
pSourceFileReceivedKey IN NUMBER,
|
||||||
|
pDestination IN VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DELETE_FOLDER_CONTENTS
|
||||||
|
* @desc It deletes all files from specified folder in the cloud storage.
|
||||||
|
* The procedure lists all objects in the specified folder prefix and deletes them one by one.
|
||||||
|
* pBucketArea parameter specifies which bucket to use: 'INBOX', 'DATA', 'ARCHIVE'
|
||||||
|
* pFolderPrefix parameter specifies the folder path within the bucket (e.g., 'C2D/UC_DISSEM/UC_NMA_DISSEM/')
|
||||||
|
* @example exec FILE_MANAGER.DELETE_FOLDER_CONTENTS(pBucketArea => 'INBOX', pFolderPrefix => 'C2D/UC_DISSEM/UC_NMA_DISSEM/');
|
||||||
|
**/
|
||||||
|
PROCEDURE DELETE_FOLDER_CONTENTS(
|
||||||
|
pBucketArea IN VARCHAR2,
|
||||||
|
pFolderPrefix IN VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name PROCESS_SOURCE_FILE
|
||||||
|
* @desc It process file provided by pSourceFileReceivedName parameter.
|
||||||
|
* Ubmrella procedure that calls:
|
||||||
|
* - REGISTER_SOURCE_FILE_RECEIVED;
|
||||||
|
* - CREATE_EXTERNAL_TABLE;
|
||||||
|
* - VALIDATE_SOURCE_FILE_RECEIVED;
|
||||||
|
* - DROP_EXTERNAL_TABLE;
|
||||||
|
* - MOVE_FILE;
|
||||||
|
* @example exec FILE_MANAGER.PROCESS_SOURCE_FILE(pSourceFileReceivedName => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv');
|
||||||
|
**/
|
||||||
|
PROCEDURE PROCESS_SOURCE_FILE(pSourceFileReceivedName IN VARCHAR2)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name PROCESS_SOURCE_FILE
|
||||||
|
* @desc It process file provided by pSourceFileReceivedName parameter and return processing result value.
|
||||||
|
* It returns (success/failure) => 0 / -(value).
|
||||||
|
* Ubmrella function that calls PROCESS_SOURCE_FILE procedure.
|
||||||
|
* @example
|
||||||
|
* declare
|
||||||
|
* vResult PLS_INTEGER;
|
||||||
|
* begin
|
||||||
|
* vResult := CT_MRDS.FILE_MANAGER.PROCESS_SOURCE_FILE(PSOURCEFILERECEIVEDNAME => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv');
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vResult = ' || vResult);
|
||||||
|
* end;
|
||||||
|
* @ex_rslt 0
|
||||||
|
* -20021
|
||||||
|
**/
|
||||||
|
FUNCTION PROCESS_SOURCE_FILE(pSourceFileReceivedName IN VARCHAR2)
|
||||||
|
RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_DATE_FORMAT
|
||||||
|
* @desc Returns date format for specified template table name and column name.
|
||||||
|
* Date is taken from configuration A_COLUMN_DATE_FORMAT table.
|
||||||
|
* @example select FILE_MANAGER.GET_DATE_FORMAT(
|
||||||
|
* pTemplateTableName => 'STANDING_FACILITIES_HEADER',
|
||||||
|
* pColumnName => 'SNAPSHOT_DATE')
|
||||||
|
* from dual;
|
||||||
|
* @ex_rslt DD/MM/YYYY HH24:MI:SS
|
||||||
|
**/
|
||||||
|
FUNCTION GET_DATE_FORMAT(
|
||||||
|
pTemplateTableName IN VARCHAR2,
|
||||||
|
pColumnName IN VARCHAR2
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GENERATE_EXTERNAL_TABLE_PARAMS
|
||||||
|
* @desc It builds two strings: pColumnList and pFieldList for specified Template Table name, by parameter: pTemplateTableName.
|
||||||
|
* @example
|
||||||
|
* declare
|
||||||
|
* vColumnList CLOB;
|
||||||
|
* vFieldList CLOB;
|
||||||
|
* begin
|
||||||
|
* FILE_MANAGER.GENERATE_EXTERNAL_TABLE_PARAMS (
|
||||||
|
* pTemplateTableName => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER'
|
||||||
|
* ,pColumnList => vColumnList
|
||||||
|
* ,pFieldList => vFieldList
|
||||||
|
* );
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vColumnList = '||vColumnList);
|
||||||
|
* DBMS_OUTPUT.PUT_LINE('vFieldList = '||vFieldList);
|
||||||
|
* end;
|
||||||
|
* /
|
||||||
|
**/
|
||||||
|
PROCEDURE GENERATE_EXTERNAL_TABLE_PARAMS (
|
||||||
|
pTemplateTableName IN VARCHAR2,
|
||||||
|
pColumnList OUT CLOB,
|
||||||
|
pFieldList OUT CLOB
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ADD_SOURCE
|
||||||
|
* @desc Insert a new record to A_SOURCE table.
|
||||||
|
* pSourceKey is a PRIMARY KEY value.
|
||||||
|
**/
|
||||||
|
PROCEDURE ADD_SOURCE (
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE,
|
||||||
|
pSourceName IN CT_MRDS.A_SOURCE.SOURCE_NAME%TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DELETE_SOURCE_CASCADE
|
||||||
|
* @desc Safely deletes a SOURCE specified by pSourceKey parameter from A_SOURCE table and all dependent tables:
|
||||||
|
* - A_SOURCE_FILE_CONFIG
|
||||||
|
* - A_SOURCE_FILE_RECEIVED
|
||||||
|
* - A_COLUMN_DATE_FORMAT (only if template table is not shared with other source systems)
|
||||||
|
* The procedure checks if template tables are shared before deleting date format configurations.
|
||||||
|
* If a template table is used by multiple source systems, date formats are preserved.
|
||||||
|
* @example CALL CT_MRDS.FILE_MANAGER.DELETE_SOURCE_CASCADE(pSourceKey => 'TEST_SYS');
|
||||||
|
**/
|
||||||
|
PROCEDURE DELETE_SOURCE_CASCADE (
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_CONTAINER_SOURCE_FILE_CONFIG_KEY
|
||||||
|
* @desc For specified parameter pSourceFileId (A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID)
|
||||||
|
* it returns A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY for related CONTAINER record.
|
||||||
|
* @example select FILE_MANAGER.GET_CONTAINER_SOURCE_FILE_CONFIG_KEY(
|
||||||
|
* pSourceFileId => 'UC_DISSEM')
|
||||||
|
* from dual;
|
||||||
|
* @ex_rslt 126
|
||||||
|
**/
|
||||||
|
FUNCTION GET_CONTAINER_SOURCE_FILE_CONFIG_KEY (
|
||||||
|
pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_SOURCE_FILE_CONFIG_KEY
|
||||||
|
* @desc For specified input parameters,
|
||||||
|
* it returns A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY.
|
||||||
|
* @example select FILE_MANAGER.GET_SOURCE_FILE_CONFIG_KEY (
|
||||||
|
* pSourceFileType => 'INPUT'
|
||||||
|
* ,pSourceFileId => 'UC_DISSEM'
|
||||||
|
* ,pTableId => 'UC_NMA_DISSEM')
|
||||||
|
* from dual;
|
||||||
|
* @ex_rslt 126
|
||||||
|
**/
|
||||||
|
FUNCTION GET_SOURCE_FILE_CONFIG_KEY (
|
||||||
|
pSourceFileType IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE%TYPE DEFAULT 'INPUT'
|
||||||
|
,pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE
|
||||||
|
,pTableId IN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID%TYPE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ADD_SOURCE_FILE_CONFIG
|
||||||
|
* @desc Insert a new record to A_SOURCE_FILE_CONFIG table.
|
||||||
|
* MARS-1049: Added pEncoding parameter for CSV character set specification.
|
||||||
|
* @param pEncoding - Character set encoding for CSV files (e.g., 'UTF8', 'WE8MSWIN1252', 'EE8ISO8859P2')
|
||||||
|
* If NULL, no CHARACTERSET clause is added to external table definitions
|
||||||
|
* @example CALL CT_MRDS.FILE_MANAGER.ADD_SOURCE_FILE_CONFIG(
|
||||||
|
* pSourceKey => 'C2D', pSourceFileType => 'INPUT',
|
||||||
|
* pSourceFileId => 'UC_DISSEM', pTableId => 'METADATA_LOADS',
|
||||||
|
* pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
||||||
|
* pEncoding => 'UTF8'
|
||||||
|
* );
|
||||||
|
**/
|
||||||
|
PROCEDURE ADD_SOURCE_FILE_CONFIG (
|
||||||
|
pSourceKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_KEY%TYPE
|
||||||
|
,pSourceFileType IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE%TYPE
|
||||||
|
,pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE
|
||||||
|
,pSourceFileDesc IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_DESC%TYPE
|
||||||
|
,pSourceFileNamePattern IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_NAME_PATTERN%TYPE
|
||||||
|
,pTableId IN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID%TYPE DEFAULT NULL
|
||||||
|
,pTemplateTableName IN CT_MRDS.A_SOURCE_FILE_CONFIG.TEMPLATE_TABLE_NAME%TYPE DEFAULT NULL
|
||||||
|
,pContainerFileKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.CONTAINER_FILE_KEY%TYPE DEFAULT NULL
|
||||||
|
,pEncoding IN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING%TYPE DEFAULT NULL -- MARS-1049: NOWY PARAMETR
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ADD_COLUMN_DATE_FORMAT
|
||||||
|
* @desc Insert a new record to A_COLUMN_DATE_FORMAT table.
|
||||||
|
**/
|
||||||
|
PROCEDURE ADD_COLUMN_DATE_FORMAT (
|
||||||
|
pTemplateTableName IN CT_MRDS.A_COLUMN_DATE_FORMAT.TEMPLATE_TABLE_NAME%TYPE
|
||||||
|
,pColumnName IN CT_MRDS.A_COLUMN_DATE_FORMAT.COLUMN_NAME%TYPE
|
||||||
|
,pDateFormat IN CT_MRDS.A_COLUMN_DATE_FORMAT.DATE_FORMAT%TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_BUCKET_URI
|
||||||
|
* @desc Function used to get string with bucket http url.
|
||||||
|
* Possible input values for pBucketArea are: 'INBOX', 'ODS', 'DATA', 'ARCHIVE'
|
||||||
|
* @example select FILE_MANAGER.GET_BUCKET_URI(pBucketArea => 'ODS') from dual;
|
||||||
|
* @ex_rslt https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/frcnomajoc7v/b/mrds_data_tst/o/
|
||||||
|
**/
|
||||||
|
FUNCTION GET_BUCKET_URI(pBucketArea VARCHAR2)
|
||||||
|
RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_DET_SOURCE_FILE_CONFIG_INFO
|
||||||
|
* @desc Function returns details about A_SOURCE_FILE_CONFIG record
|
||||||
|
* for specified pSourceFileConfigKey (A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY).
|
||||||
|
* If pIncludeContainerInfo is <> 0 it returns additional info about related Container config record (A_SOURCE_FILE_CONFIG)
|
||||||
|
* If pIncludeColumnFormatInfo is <> 0 it returns additional info about related ColumnFormat config record (A_COLUMN_DATE_FORMAT)
|
||||||
|
* @example select FILE_MANAGER.GET_DET_SOURCE_FILE_CONFIG_INFO (
|
||||||
|
* pSourceFileConfigKey => 128
|
||||||
|
* ,pIncludeContainerInfo => 1
|
||||||
|
* ,pIncludeColumnFormatInfo => 1
|
||||||
|
* ) from dual;
|
||||||
|
* @ex_rslt
|
||||||
|
* Details about File Configuration:
|
||||||
|
* --------------------------------
|
||||||
|
* A_SOURCE_FILE_CONFIG_KEY = 128
|
||||||
|
* A_SOURCE_KEY = C2D
|
||||||
|
* ...
|
||||||
|
* --------------------------------
|
||||||
|
*
|
||||||
|
* Details about related Container Config:
|
||||||
|
* --------------------------------
|
||||||
|
* A_SOURCE_FILE_CONFIG_KEY = 126
|
||||||
|
* A_SOURCE_KEY = C2D
|
||||||
|
* ...
|
||||||
|
* --------------------------------
|
||||||
|
*
|
||||||
|
* Column Date Format config entries:
|
||||||
|
* --------------------------------
|
||||||
|
* TEMPLATE_TABLE_NAME = CT_ET_TEMPLATES.C2D_UC_MA_DISSEM
|
||||||
|
* ...
|
||||||
|
* --------------------------------
|
||||||
|
**/
|
||||||
|
FUNCTION GET_DET_SOURCE_FILE_CONFIG_INFO (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
||||||
|
,pIncludeContainerInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
,pIncludeColumnFormatInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_DET_SOURCE_FILE_RECEIVED_INFO
|
||||||
|
* @desc Function returns details about A_SOURCE_FILE_RECEIVED record
|
||||||
|
* for specified pSourceFileReceivedKey (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY).
|
||||||
|
* If pIncludeConfigInfo is <> 0 it returns additional info about related Container config record (A_SOURCE_FILE_CONFIG)
|
||||||
|
* If pIncludeContainerInfo is <> 0 it returns additional info about related Container config record (A_SOURCE_FILE_CONFIG)
|
||||||
|
* If pIncludeColumnFormatInfo is <> 0 it returns additional info about related ColumnFormat config record (A_COLUMN_DATE_FORMAT)
|
||||||
|
* @example select FILE_MANAGER.GET_DET_SOURCE_FILE_RECEIVED_INFO (
|
||||||
|
* pSourceFileReceivedKey => 377
|
||||||
|
* ,pIncludeConfigInfo => 1
|
||||||
|
* ,pIncludeContainerInfo => 1
|
||||||
|
* ,pIncludeColumnFormatInfo => 1
|
||||||
|
* ) from dual;
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
FUNCTION GET_DET_SOURCE_FILE_RECEIVED_INFO (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE
|
||||||
|
,pIncludeConfigInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
,pIncludeContainerInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
,pIncludeColumnFormatInfo IN PLS_INTEGER DEFAULT 1
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_DET_USER_LOAD_OPERATIONS
|
||||||
|
* @desc Function returns details from USER_LOAD_OPERATIONS table
|
||||||
|
* for specified pOperationId.
|
||||||
|
* @example select FILE_MANAGER.GET_DET_USER_LOAD_OPERATIONS (pOperationId => 3608) from dual;
|
||||||
|
* @ex_rslt
|
||||||
|
* Details about USER_LOAD_OPERATIONS where ID = 3608
|
||||||
|
* --------------------------------
|
||||||
|
* ID = 3608
|
||||||
|
* TYPE = VALIDATE
|
||||||
|
* SID = 31260
|
||||||
|
* SERIAL# = 52915
|
||||||
|
* START_TIME = 2025-05-20 10.08.24.436983 EUROPE/BELGRADE
|
||||||
|
* UPDATE_TIME = 2025-05-20 10.08.24.458643 EUROPE/BELGRADE
|
||||||
|
* STATUS = FAILED
|
||||||
|
* OWNER_NAME = CT_MRDS
|
||||||
|
* TABLE_NAME = STANDING_FACILITIES_HEADER
|
||||||
|
* PARTITION_NAME =
|
||||||
|
* SUBPARTITION_NAME =
|
||||||
|
* FILE_URI_LIST =
|
||||||
|
* ROWS_LOADED =
|
||||||
|
* LOGFILE_TABLE = VALIDATE$3608_LOG
|
||||||
|
* BADFILE_TABLE = VALIDATE$3608_BAD
|
||||||
|
* STATUS_TABLE =
|
||||||
|
* TEMPEXT_TABLE =
|
||||||
|
* CREDENTIAL_NAME =
|
||||||
|
* EXPIRATION_TIME = 2025-05-22 10.08.24.436983000 EUROPE/BELGRADE
|
||||||
|
* --------------------------------
|
||||||
|
**/
|
||||||
|
FUNCTION GET_DET_USER_LOAD_OPERATIONS (
|
||||||
|
pOperationId PLS_INTEGER
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ANALYZE_VALIDATION_ERRORS
|
||||||
|
* @desc Wrapper function that analyzes validation errors for a source file using its received key.
|
||||||
|
* Automatically derives template schema, table name, CSV URI and validation log table
|
||||||
|
* from file metadata and calls ENV_MANAGER.ANALYZE_VALIDATION_ERRORS.
|
||||||
|
* @example SELECT FILE_MANAGER.ANALYZE_VALIDATION_ERRORS(63) FROM DUAL;
|
||||||
|
* @ex_rslt Detailed validation analysis report with column mismatches and solutions
|
||||||
|
**/
|
||||||
|
FUNCTION ANALYZE_VALIDATION_ERRORS(
|
||||||
|
pSourceFileReceivedKey IN NUMBER
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- PACKAGE VERSION MANAGEMENT FUNCTIONS
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_VERSION
|
||||||
|
* @desc Returns the current version number of the FILE_MANAGER package.
|
||||||
|
* Uses semantic versioning format (MAJOR.MINOR.PATCH).
|
||||||
|
* @example SELECT FILE_MANAGER.GET_VERSION() FROM DUAL;
|
||||||
|
* @ex_rslt 3.2.0
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_BUILD_INFO
|
||||||
|
* @desc Returns comprehensive build information including version, build date, and author.
|
||||||
|
* Uses centralized ENV_MANAGER.GET_PACKAGE_VERSION_INFO function.
|
||||||
|
* @example SELECT FILE_MANAGER.GET_BUILD_INFO() FROM DUAL;
|
||||||
|
* @ex_rslt Package: FILE_MANAGER
|
||||||
|
* Version: 3.2.0
|
||||||
|
* Build Date: 2025-10-22 16:30:00
|
||||||
|
* Author: Grzegorz Michalski
|
||||||
|
**/
|
||||||
|
FUNCTION GET_BUILD_INFO RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_VERSION_HISTORY
|
||||||
|
* @desc Returns complete version history with all releases and changes.
|
||||||
|
* Uses centralized ENV_MANAGER.FORMAT_VERSION_HISTORY function.
|
||||||
|
* @example SELECT FILE_MANAGER.GET_VERSION_HISTORY() FROM DUAL;
|
||||||
|
* @ex_rslt FILE_MANAGER Version History:
|
||||||
|
* 3.2.0 (2025-10-22): Added package versioning system...
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2;
|
||||||
|
|
||||||
|
END;
|
||||||
|
|
||||||
|
/
|
||||||
|
|
||||||
|
/
|
||||||
@@ -181,7 +181,7 @@ AS
|
|||||||
BEGIN
|
BEGIN
|
||||||
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
SET PROCESSING_STATUS = 'ARCHIVED'
|
SET PROCESSING_STATUS = 'ARCHIVED'
|
||||||
,ARCH_FILE_NAME = vUri||vFilename
|
,ARCH_PATH = vUri||vFilename
|
||||||
WHERE r.a_source_file_config_key= pSourceFileConfigKey
|
WHERE r.a_source_file_config_key= pSourceFileConfigKey
|
||||||
AND r.source_file_name = f.filename
|
AND r.source_file_name = f.filename
|
||||||
AND r.processing_status = 'INGESTED'
|
AND r.processing_status = 'INGESTED'
|
||||||
@@ -244,7 +244,7 @@ AS
|
|||||||
|
|
||||||
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
SET PROCESSING_STATUS = 'INGESTED'
|
SET PROCESSING_STATUS = 'INGESTED'
|
||||||
,ARCH_FILE_NAME = NULL
|
,ARCH_PATH = NULL
|
||||||
WHERE r.a_source_file_config_key = pSourceFileConfigKey
|
WHERE r.a_source_file_config_key = pSourceFileConfigKey
|
||||||
AND r.source_file_name = f.filename
|
AND r.source_file_name = f.filename
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ AS
|
|||||||
BEGIN
|
BEGIN
|
||||||
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
SET PROCESSING_STATUS = 'ARCHIVED'
|
SET PROCESSING_STATUS = 'ARCHIVED'
|
||||||
,ARCH_FILE_NAME = vUri||vFilename
|
,ARCH_PATH = vUri||vFilename
|
||||||
WHERE r.a_source_file_config_key= pSourceFileConfigKey
|
WHERE r.a_source_file_config_key= pSourceFileConfigKey
|
||||||
AND r.source_file_name = f.filename
|
AND r.source_file_name = f.filename
|
||||||
AND r.processing_status = 'INGESTED'
|
AND r.processing_status = 'INGESTED'
|
||||||
@@ -294,7 +294,7 @@ AS
|
|||||||
|
|
||||||
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
SET PROCESSING_STATUS = 'INGESTED'
|
SET PROCESSING_STATUS = 'INGESTED'
|
||||||
,ARCH_FILE_NAME = NULL
|
,ARCH_PATH = NULL
|
||||||
WHERE r.a_source_file_config_key = pSourceFileConfigKey
|
WHERE r.a_source_file_config_key = pSourceFileConfigKey
|
||||||
AND r.source_file_name = f.filename
|
AND r.source_file_name = f.filename
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -0,0 +1,998 @@
|
|||||||
|
create or replace PACKAGE BODY CT_MRDS.FILE_ARCHIVER
|
||||||
|
AS
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-- PRIVATE FUNCTION: GET_ARCHIVAL_WHERE_CLAUSE
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @name GET_ARCHIVAL_WHERE_CLAUSE
|
||||||
|
* @desc Private function that generates WHERE clause based on ARCHIVAL_STRATEGY configuration.
|
||||||
|
* Supports three strategies: THRESHOLD_BASED, MINIMUM_AGE_MONTHS, HYBRID.
|
||||||
|
* @param pSourceFileConfig - Source file configuration record with ARCHIVAL_STRATEGY
|
||||||
|
* @return VARCHAR2 - WHERE clause for filtering archival candidates
|
||||||
|
**/
|
||||||
|
FUNCTION GET_ARCHIVAL_WHERE_CLAUSE(
|
||||||
|
pSourceFileConfig IN CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE
|
||||||
|
) RETURN VARCHAR2
|
||||||
|
IS
|
||||||
|
vWhereClause VARCHAR2(4000);
|
||||||
|
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
||||||
|
BEGIN
|
||||||
|
CASE pSourceFileConfig.ARCHIVAL_STRATEGY
|
||||||
|
-- Legacy threshold-based strategy (backward compatible)
|
||||||
|
WHEN 'THRESHOLD_BASED' THEN
|
||||||
|
vWhereClause := 'extract(day from (systimestamp - workflow_start)) > ' || pSourceFileConfig.DAYS_FOR_ARCHIVE_THRESHOLD;
|
||||||
|
|
||||||
|
-- Archive data older than X months (0 = current month only)
|
||||||
|
WHEN 'MINIMUM_AGE_MONTHS' THEN
|
||||||
|
IF pSourceFileConfig.MINIMUM_AGE_MONTHS IS NULL THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20001, 'MINIMUM_AGE_MONTHS must be configured for MINIMUM_AGE_MONTHS strategy');
|
||||||
|
END IF;
|
||||||
|
vWhereClause := 'workflow_start < ADD_MONTHS(TRUNC(SYSDATE, ''MM''), -' || pSourceFileConfig.MINIMUM_AGE_MONTHS || ')';
|
||||||
|
|
||||||
|
-- Hybrid: Current month exclusion AND minimum age requirement
|
||||||
|
WHEN 'HYBRID' THEN
|
||||||
|
IF pSourceFileConfig.MINIMUM_AGE_MONTHS IS NULL THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20001, 'MINIMUM_AGE_MONTHS must be configured for HYBRID strategy');
|
||||||
|
END IF;
|
||||||
|
vWhereClause := 'TRUNC(workflow_start, ''MM'') < TRUNC(SYSDATE, ''MM'') ' ||
|
||||||
|
'AND workflow_start < ADD_MONTHS(TRUNC(SYSDATE, ''MM''), -' || pSourceFileConfig.MINIMUM_AGE_MONTHS || ')';
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
RAISE_APPLICATION_ERROR(-20002, 'Invalid ARCHIVAL_STRATEGY: ' || pSourceFileConfig.ARCHIVAL_STRATEGY);
|
||||||
|
END CASE;
|
||||||
|
|
||||||
|
RETURN vWhereClause;
|
||||||
|
END GET_ARCHIVAL_WHERE_CLAUSE;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FUNCTION GET_TABLE_STAT(pSourceFileConfigKey IN NUMBER)
|
||||||
|
RETURN CT_MRDS.A_TABLE_STAT%ROWTYPE
|
||||||
|
IS
|
||||||
|
vTableStat CT_MRDS.A_TABLE_STAT%ROWTYPE;
|
||||||
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
|
vCount PLS_INTEGER;
|
||||||
|
vSourceFileType CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE%TYPE;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey),NULL)));
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters);
|
||||||
|
SELECT count(*) , min(SOURCE_FILE_TYPE)
|
||||||
|
INTO vCount, vSourceFileType
|
||||||
|
FROM CT_MRDS.A_TABLE_STAT s
|
||||||
|
JOIN CT_MRDS.A_SOURCE_FILE_CONFIG c
|
||||||
|
ON s.A_SOURCE_FILE_CONFIG_KEY = c.A_SOURCE_FILE_CONFIG_KEY
|
||||||
|
WHERE s.A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey;
|
||||||
|
|
||||||
|
IF vCount=0 and vSourceFileType='INPUT' THEN
|
||||||
|
GATHER_TABLE_STAT(pSourceFileConfigKey);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
SELECT *
|
||||||
|
INTO vTableStat
|
||||||
|
FROM CT_MRDS.A_TABLE_STAT
|
||||||
|
WHERE A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey;
|
||||||
|
-- EXCEPTION
|
||||||
|
-- WHEN NO_DATA_FOUND THEN
|
||||||
|
--
|
||||||
|
END;
|
||||||
|
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters);
|
||||||
|
RETURN vTableStat;
|
||||||
|
|
||||||
|
END GET_TABLE_STAT;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PROCEDURE ARCHIVE_TABLE_DATA (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE,
|
||||||
|
pKeepInTrash IN BOOLEAN DEFAULT TRUE
|
||||||
|
)
|
||||||
|
IS
|
||||||
|
vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE;
|
||||||
|
vTableStat CT_MRDS.A_TABLE_STAT%ROWTYPE;
|
||||||
|
vQuery VARCHAR2(4000);
|
||||||
|
vTableName VARCHAR2(200);
|
||||||
|
vUri VARCHAR2(1000);
|
||||||
|
vfiles T_FILENAMES;
|
||||||
|
vFilename VARCHAR2(300);
|
||||||
|
vOperationId NUMBER := -1;
|
||||||
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
|
vArchivalTriggeredBy VARCHAR2(60); -- Possible values: FILES_COUNT, ROWS_COUNT, BYTES_SUM
|
||||||
|
vUserLoadOperations USER_LOAD_OPERATIONS%ROWTYPE;
|
||||||
|
vProcessControlStatus VARCHAR2(60) := 'OK';
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
||||||
|
'pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL'),
|
||||||
|
'pKeepInTrash => '||CASE WHEN pKeepInTrash THEN 'TRUE' ELSE 'FALSE' END
|
||||||
|
));
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
|
||||||
|
vSourceFileConfig := CT_MRDS.FILE_MANAGER.GET_SOURCE_FILE_CONFIG(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
vTableStat := GET_TABLE_STAT(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
|
||||||
|
if vSourceFileConfig.SOURCE_FILE_TYPE <> 'INPUT' then
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.MSG_NOT_INPUT_SOURCE_FILE_TYPE, 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_NOT_INPUT_SOURCE_FILE_TYPE, CT_MRDS.ENV_MANAGER.MSG_NOT_INPUT_SOURCE_FILE_TYPE);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if vTableStat.created < sysdate-(vSourceFileConfig.HOURS_TO_EXPIRE_STATISTICS/24) then
|
||||||
|
GATHER_TABLE_STAT(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
vTableStat := GET_TABLE_STAT(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- Strategy-based trigger logic (MARS-828)
|
||||||
|
IF vSourceFileConfig.ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS' THEN
|
||||||
|
-- MINIMUM_AGE_MONTHS: Archive based on age only, ignore thresholds
|
||||||
|
vArchivalTriggeredBy := 'AGE_BASED';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Archival strategy: MINIMUM_AGE_MONTHS (threshold-independent)','INFO');
|
||||||
|
ELSE
|
||||||
|
-- THRESHOLD_BASED and HYBRID: Check thresholds
|
||||||
|
if vTableStat.OVER_ARCH_THRESOLD_FILE_COUNT >= vSourceFileConfig.FILES_COUNT_OVER_ARCHIVE_THRESHOLD then vArchivalTriggeredBy := 'FILES_COUNT';
|
||||||
|
elsif vTableStat.OVER_ARCH_THRESOLD_ROW_COUNT >= vSourceFileConfig.ROWS_COUNT_OVER_ARCHIVE_THRESHOLD then vArchivalTriggeredBy := vArchivalTriggeredBy||', ROWS_COUNT';
|
||||||
|
elsif vTableStat.OVER_ARCH_THRESOLD_SIZE >= vSourceFileConfig.BYTES_SUM_OVER_ARCHIVE_THRESHOLD then vArchivalTriggeredBy := vArchivalTriggeredBy||', BYTES_SUM';
|
||||||
|
else CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Non of archival triggers reached','INFO');
|
||||||
|
end if;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
if LENGTH(vArchivalTriggeredBy)>0 THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Archival Triggered By: '||vArchivalTriggeredBy,'INFO');
|
||||||
|
vTableName := DBMS_ASSERT.SCHEMA_NAME(vSourceFileConfig.ODS_SCHEMA_NAME) || '.'||DBMS_ASSERT.simple_sql_name(vSourceFileConfig.TABLE_ID)||'_ODS';
|
||||||
|
|
||||||
|
-- Use strategy-based WHERE clause (MARS-828)
|
||||||
|
-- Using GROUP BY instead of DISTINCT to avoid ORA-22950 (object type ordering issue)
|
||||||
|
vQuery := '
|
||||||
|
select CT_MRDS.t_filename(
|
||||||
|
file$name
|
||||||
|
,file$path
|
||||||
|
, to_char(h.workflow_start,''yyyy'')
|
||||||
|
, to_char(h.workflow_start,''mm'')
|
||||||
|
)
|
||||||
|
from '||vTableName||' s
|
||||||
|
join CT_MRDS.a_workflow_history h
|
||||||
|
on s.a_workflow_history_key = h.a_workflow_history_key
|
||||||
|
where ' || GET_ARCHIVAL_WHERE_CLAUSE(vSourceFileConfig) || '
|
||||||
|
group by file$name, file$path, to_char(h.workflow_start,''yyyy''), to_char(h.workflow_start,''mm'')'
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Get all files that will be archived into "vfiles" collection ("regular data files")
|
||||||
|
execute immediate vQuery bulk collect into vfiles;
|
||||||
|
|
||||||
|
-- Start EXPORT "regular data files" to parquet and DROP "csv"
|
||||||
|
FOR ym_loop IN (select distinct year, month from table(vfiles) order by 1,2) LOOP
|
||||||
|
dbms_output.put_line('year: '||ym_loop.year||' - '||'month: '||ym_loop.month);
|
||||||
|
vQuery:=
|
||||||
|
'select
|
||||||
|
s.*
|
||||||
|
from '|| vTableName ||' s
|
||||||
|
join CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
|
on s.file$name = r.source_file_name
|
||||||
|
and r.a_source_file_config_key = '||pSourceFileConfigKey||'
|
||||||
|
and r.PROCESSING_STATUS = ''INGESTED''
|
||||||
|
join CT_MRDS.a_workflow_history h
|
||||||
|
on s.a_workflow_history_key = h.a_workflow_history_key
|
||||||
|
and to_char(h.workflow_start,''yyyy'') = '''||ym_loop.year||'''
|
||||||
|
and to_char(h.workflow_start,''mm'') = '''||ym_loop.month||'''
|
||||||
|
'
|
||||||
|
;
|
||||||
|
vUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ARCHIVE')||vSourceFileConfig.A_SOURCE_KEY||'/'||vSourceFileConfig.TABLE_ID||'/PARTITION_YEAR='||ym_loop.year||'/PARTITION_MONTH='||ym_loop.month||'/';
|
||||||
|
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start Archiving for YEAR_MONTH: '||ym_loop.year||'_'||ym_loop.month ,'INFO');
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Parameter for DBMS_CLOUD.EXPORT_DATA => file_uri_list' ,'DEBUG',vUri);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Parameter for DBMS_CLOUD.EXPORT_DATA => query' ,'DEBUG',vQuery);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.EXPORT_DATA(
|
||||||
|
credential_name => ENV_MANAGER.gvCredentialName,
|
||||||
|
file_uri_list => vUri||'d' ,
|
||||||
|
format => json_object('type' value 'parquet'),
|
||||||
|
query => vQuery,
|
||||||
|
operation_id => vOperationId
|
||||||
|
);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
vProcessControlStatus :='EXPORT_FAILURE';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_EXP_DATA_FOR_ARCH_FAILED, CT_MRDS.ENV_MANAGER.MSG_EXP_DATA_FOR_ARCH_FAILED);
|
||||||
|
|
||||||
|
END;
|
||||||
|
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('vOperationId of export: '||vOperationId,'DEBUG');
|
||||||
|
|
||||||
|
-- Get USER_LOAD_OPERATIONS info
|
||||||
|
select *
|
||||||
|
into vUserLoadOperations
|
||||||
|
from USER_LOAD_OPERATIONS
|
||||||
|
where id = vOperationId;
|
||||||
|
|
||||||
|
IF vUserLoadOperations.STATUS <>'COMPLETED' THEN
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_EXP_DATA_FOR_ARCH_FAILED,
|
||||||
|
CT_MRDS.ENV_MANAGER.MSG_EXP_DATA_FOR_ARCH_FAILED ||cgBL|| ' Export ended with status '||vUserLoadOperations.STATUS);
|
||||||
|
ELSIF vUserLoadOperations.STATUS = 'COMPLETED' and vUserLoadOperations.ROWS_LOADED = 0 THEN
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_EXP_DATA_FOR_ARCH_FAILED,
|
||||||
|
CT_MRDS.ENV_MANAGER.MSG_EXP_DATA_FOR_ARCH_FAILED ||cgBL|| ' Zero rows were exported.');
|
||||||
|
ELSE
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Data exported to archival file for YEAR_MONTH: '||ym_loop.year||'_'||ym_loop.month,'INFO', vParameters);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.FILE_MANAGER.GET_DET_USER_LOAD_OPERATIONS (pOperationId => vOperationId),'DEBUG', vParameters);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Note: DBMS_CLOUD.EXPORT_DATA may create multiple parquet files (parallel execution)
|
||||||
|
-- Instead of tracking individual files, we store the archive directory prefix
|
||||||
|
-- ARCH_PATH will contain the directory URI where all parquet files are located
|
||||||
|
vFilename := vUri; -- Store directory prefix instead of individual filename
|
||||||
|
|
||||||
|
-- Try to drop EXPORTED FILES ("regular data files")
|
||||||
|
BEGIN
|
||||||
|
FOR f in (select filename, pathname from table(vfiles) where year = ym_loop.year and month = ym_loop.month) loop
|
||||||
|
|
||||||
|
-- first change of status to ARCHIVED_AND_TRASHED (file will be moved to TRASH folder)
|
||||||
|
BEGIN
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
|
SET PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED' -- Status reflects file is archived and kept in TRASH
|
||||||
|
,ARCH_PATH = vFilename -- Now contains directory prefix, not individual file
|
||||||
|
,PARTITION_YEAR = ym_loop.year -- Record which partition year the data was archived to
|
||||||
|
,PARTITION_MONTH = ym_loop.month -- Record which partition month the data was archived to
|
||||||
|
WHERE r.a_source_file_config_key= pSourceFileConfigKey
|
||||||
|
AND r.source_file_name = f.filename
|
||||||
|
AND r.processing_status = 'INGESTED'
|
||||||
|
;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
vProcessControlStatus := 'CHANGE_STATUS_TO_ARCHIVED_AND_TRASHED_FAILURE';
|
||||||
|
END;
|
||||||
|
EXIT WHEN vProcessControlStatus = 'CHANGE_STATUS_TO_ARCHIVED_AND_TRASHED_FAILURE';
|
||||||
|
|
||||||
|
-- move file to TRASH subfolder (DATA bucket: ODS/ → TRASH/) before dropping
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.MOVE_OBJECT(source_credential_name => ENV_MANAGER.gvCredentialName,
|
||||||
|
source_object_uri => f.pathname||'/'||f.filename,
|
||||||
|
target_object_uri => replace(f.pathname,'ODS','TRASH')||'/'||f.filename,
|
||||||
|
target_credential_name => ENV_MANAGER.gvCredentialName
|
||||||
|
);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('File moved to TRASH folder.','DEBUG', f.pathname||'/'||f.filename);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to move file to TRASH folder.','ERROR', f.pathname||'/'||f.filename);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
rollback;
|
||||||
|
vProcessControlStatus := 'MOVE_FILE_TO_TRASH_FAILURE';
|
||||||
|
END;
|
||||||
|
EXIT WHEN vProcessControlStatus = 'MOVE_FILE_TO_TRASH_FAILURE';
|
||||||
|
commit;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
-- IF All goes fine till this point, we drop files from TRASH folder (if not then ROLLBACK PART)
|
||||||
|
-- TRASH is a subfolder in DATA bucket (e.g., TRASH/LM/TABLE_NAME instead of ODS/LM/TABLE_NAME)
|
||||||
|
IF vProcessControlStatus = 'OK' THEN
|
||||||
|
IF NOT pKeepInTrash THEN
|
||||||
|
-- Delete files from TRASH folder (cleanup) and update status to ARCHIVED_AND_PURGED
|
||||||
|
FOR f in (select filename, pathname from table(vfiles) where year = ym_loop.year and month = ym_loop.month) LOOP
|
||||||
|
DBMS_CLOUD.DELETE_OBJECT(credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
object_uri => replace(f.pathname,'ODS','TRASH')||'/'||f.filename);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('File dropped from TRASH folder.','DEBUG', f.pathname||'/'||f.filename);
|
||||||
|
|
||||||
|
-- Update status to ARCHIVED_AND_PURGED
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
|
SET PROCESSING_STATUS = 'ARCHIVED_AND_PURGED'
|
||||||
|
WHERE r.a_source_file_config_key = pSourceFileConfigKey
|
||||||
|
AND r.source_file_name = f.filename
|
||||||
|
AND r.PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
END LOOP;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('All archived files removed from TRASH folder and marked as ARCHIVED_AND_PURGED.','INFO');
|
||||||
|
ELSE
|
||||||
|
-- Keep files in TRASH folder (status remains ARCHIVED_AND_TRASHED)
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Archived files kept in TRASH folder for retention (status: ARCHIVED_AND_TRASHED).','INFO');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
--ROLLBACK PART
|
||||||
|
--ROLLBACK PROCESS in case of FAILURE (restore files from TRASH subfolder in DATA bucket)
|
||||||
|
ELSIF vProcessControlStatus = 'MOVE_FILE_TO_TRASH_FAILURE' THEN
|
||||||
|
FOR f in ( SELECT vf.filename, vf.pathname
|
||||||
|
FROM TABLE(vfiles) vf
|
||||||
|
JOIN CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
|
ON r.source_file_name = vf.filename
|
||||||
|
AND r.a_source_file_config_key = pSourceFileConfigKey
|
||||||
|
AND r.PROCESSING_STATUS IN ('ARCHIVED_AND_TRASHED', 'ARCHIVED_AND_PURGED')
|
||||||
|
AND vf.year = ym_loop.year
|
||||||
|
AND vf.month = ym_loop.month
|
||||||
|
) LOOP
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.MOVE_OBJECT(source_credential_name => ENV_MANAGER.gvCredentialName,
|
||||||
|
source_object_uri => replace(f.pathname,'ODS','TRASH')||'/'||f.filename,
|
||||||
|
target_object_uri => f.pathname||'/'||f.filename,
|
||||||
|
target_credential_name => ENV_MANAGER.gvCredentialName
|
||||||
|
);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('File restored from TRASH folder.','DEBUG', f.pathname||'/'||f.filename);
|
||||||
|
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
|
SET PROCESSING_STATUS = 'INGESTED'
|
||||||
|
,ARCH_PATH = NULL
|
||||||
|
WHERE r.a_source_file_config_key = pSourceFileConfigKey
|
||||||
|
AND r.source_file_name = f.filename
|
||||||
|
;
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to restore file from TRASH folder.','ERROR', replace(f.pathname,'ODS','TRASH')||'/'||f.filename);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
vProcessControlStatus := 'RESTORE_FILE_FROM_TRASH_FAILURE';
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
-- ROLLBACK: Delete all parquet files from archive directory
|
||||||
|
FOR arch_file IN (
|
||||||
|
SELECT object_name
|
||||||
|
FROM DBMS_CLOUD.LIST_OBJECTS(
|
||||||
|
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
location_uri => vFilename -- vFilename now contains directory prefix
|
||||||
|
)
|
||||||
|
) LOOP
|
||||||
|
DBMS_CLOUD.DELETE_OBJECT(
|
||||||
|
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
object_uri => vFilename || arch_file.object_name
|
||||||
|
);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('ROLLBACK operation: Archival PARQUET file dropped.','DEBUG', vFilename || arch_file.object_name);
|
||||||
|
END LOOP;
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_MOVE_FILE_TO_TRASH_FAILED, CT_MRDS.ENV_MANAGER.MSG_MOVE_FILE_TO_TRASH_FAILED);
|
||||||
|
|
||||||
|
ELSIF vProcessControlStatus = 'CHANGE_STATUS_TO_ARCHIVED_FAILURE' THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.MSG_CHANGE_STAT_TO_ARCHIVED_FAILED, 'ERROR', vParameters);
|
||||||
|
-- ROLLBACK: Delete all parquet files from archive directory
|
||||||
|
FOR arch_file IN (
|
||||||
|
SELECT object_name
|
||||||
|
FROM DBMS_CLOUD.LIST_OBJECTS(
|
||||||
|
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
location_uri => vFilename -- vFilename now contains directory prefix
|
||||||
|
)
|
||||||
|
) LOOP
|
||||||
|
DBMS_CLOUD.DELETE_OBJECT(
|
||||||
|
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
object_uri => vFilename || arch_file.object_name
|
||||||
|
);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Archival PARQUET file dropped.','DEBUG', vFilename || arch_file.object_name);
|
||||||
|
END LOOP;
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_CHANGE_STAT_TO_ARCHIVED_FAILED, CT_MRDS.ENV_MANAGER.MSG_CHANGE_STAT_TO_ARCHIVED_FAILED);
|
||||||
|
|
||||||
|
ELSIF vProcessControlStatus = 'RESTORE_FILE_FROM_TRASH_FAILURE' THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Some files were not restored from TRASH. Check A_PROCESS_LOG table for details','ERROR');
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_RESTORE_FILE_FROM_TRASH, CT_MRDS.ENV_MANAGER.MSG_RESTORE_FILE_FROM_TRASH);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN CT_MRDS.ENV_MANAGER.ERR_CHANGE_STAT_TO_ARCHIVED_FAILED THEN
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_CHANGE_STAT_TO_ARCHIVED_FAILED, CT_MRDS.ENV_MANAGER.MSG_CHANGE_STAT_TO_ARCHIVED_FAILED);
|
||||||
|
|
||||||
|
WHEN CT_MRDS.ENV_MANAGER.ERR_MOVE_FILE_TO_TRASH_FAILED THEN
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_MOVE_FILE_TO_TRASH_FAILED, CT_MRDS.ENV_MANAGER.MSG_MOVE_FILE_TO_TRASH_FAILED);
|
||||||
|
|
||||||
|
WHEN CT_MRDS.ENV_MANAGER.ERR_RESTORE_FILE_FROM_TRASH THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_RESTORE_FILE_FROM_TRASH, CT_MRDS.ENV_MANAGER.MSG_RESTORE_FILE_FROM_TRASH);
|
||||||
|
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Error during archiving process','ERROR');
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_DROP_EXPORTED_FILES_FAILED, CT_MRDS.ENV_MANAGER.MSG_DROP_EXPORTED_FILES_FAILED);
|
||||||
|
END;
|
||||||
|
-- END of "Try to drop EXPORTED FILES"
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End Archiving for YEAR_MONTH: '||ym_loop.year||'_'||ym_loop.month ,'INFO');
|
||||||
|
END LOOP; --ym_loop end (YEAR_MONTH)
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Non of archival thresholds reached. Skip archiving.'||vArchivalTriggeredBy,'INFO');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN CT_MRDS.ENV_MANAGER.ERR_NOT_INPUT_SOURCE_FILE_TYPE THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.MSG_NOT_INPUT_SOURCE_FILE_TYPE , 'ERROR', vParameters);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_NOT_INPUT_SOURCE_FILE_TYPE, CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE));
|
||||||
|
|
||||||
|
WHEN CT_MRDS.ENV_MANAGER.ERR_EXP_DATA_FOR_ARCH_FAILED THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.MSG_EXP_DATA_FOR_ARCH_FAILED , 'ERROR', vParameters);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_EXP_DATA_FOR_ARCH_FAILED, CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE));
|
||||||
|
|
||||||
|
WHEN CT_MRDS.ENV_MANAGER.ERR_CHANGE_STAT_TO_ARCHIVED_FAILED THEN
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_CHANGE_STAT_TO_ARCHIVED_FAILED, CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE));
|
||||||
|
|
||||||
|
WHEN CT_MRDS.ENV_MANAGER.ERR_MOVE_FILE_TO_TRASH_FAILED THEN
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_MOVE_FILE_TO_TRASH_FAILED, CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE));
|
||||||
|
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_UNKNOWN, CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE));
|
||||||
|
|
||||||
|
END ARCHIVE_TABLE_DATA;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PROCEDURE GATHER_TABLE_STAT (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
||||||
|
) IS
|
||||||
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
|
vStats CT_MRDS.A_TABLE_STAT%ROWTYPE;
|
||||||
|
vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE;
|
||||||
|
vTableName VARCHAR2(200);
|
||||||
|
vQuery VARCHAR2(32000);
|
||||||
|
vWhereClause VARCHAR2(4000);
|
||||||
|
vOdsBucketUri VARCHAR2(1000);
|
||||||
|
BEGIN
|
||||||
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL')));
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
vSourceFileConfig := CT_MRDS.FILE_MANAGER.GET_SOURCE_FILE_CONFIG(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
|
||||||
|
vTableName := DBMS_ASSERT.SCHEMA_NAME(vSourceFileConfig.ODS_SCHEMA_NAME) || '.'||DBMS_ASSERT.simple_sql_name(vSourceFileConfig.TABLE_ID)||'_ODS';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('vTableName','DEBUG',vTableName);
|
||||||
|
|
||||||
|
-- Get WHERE clause based on archival strategy (MARS-828)
|
||||||
|
vWhereClause := GET_ARCHIVAL_WHERE_CLAUSE(vSourceFileConfig);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('vWhereClause','DEBUG',vWhereClause);
|
||||||
|
|
||||||
|
-- Get ODS bucket URI before building query
|
||||||
|
vOdsBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ODS') || 'ODS/' || vSourceFileConfig.A_SOURCE_KEY || '/' || vSourceFileConfig.TABLE_ID || '/';
|
||||||
|
|
||||||
|
-- Use strategy-based WHERE clause for statistics (MARS-828)
|
||||||
|
vQuery :=
|
||||||
|
'with tmp as (
|
||||||
|
select
|
||||||
|
s.*
|
||||||
|
,file$name as filename
|
||||||
|
,h.workflow_start
|
||||||
|
, to_char(h.workflow_start,''yyyy'') as year
|
||||||
|
, to_char(h.workflow_start,''mm'') as month
|
||||||
|
from '||vTableName||' s
|
||||||
|
join CT_MRDS.a_workflow_history h
|
||||||
|
on s.a_workflow_history_key = h.a_workflow_history_key
|
||||||
|
)
|
||||||
|
, tmp_gr as (
|
||||||
|
select
|
||||||
|
filename, count(*) as row_count_per_file, min(workflow_start) as workflow_start
|
||||||
|
from tmp
|
||||||
|
group by filename
|
||||||
|
)
|
||||||
|
select
|
||||||
|
NULL as A_TABLE_STAT_KEY
|
||||||
|
,'||pSourceFileConfigKey||' as A_SOURCE_FILE_CONFIG_KEY
|
||||||
|
,'''||vTableName||''' as TABLE_NAME
|
||||||
|
,count(*) as FILE_COUNT
|
||||||
|
,sum(case when ' || vWhereClause || ' then 1 else 0 end) as OLD_FILE_COUNT
|
||||||
|
,sum (row_count_per_file) as ROW_COUNT
|
||||||
|
,sum(case when ' || vWhereClause || ' then row_count_per_file else 0 end) as OLD_ROW_COUNT
|
||||||
|
,sum(r.bytes) as BYTES
|
||||||
|
,sum(case when ' || vWhereClause || ' then r.bytes else 0 end) as OLD_BYTES
|
||||||
|
,'||COALESCE(TO_CHAR(vSourceFileConfig.DAYS_FOR_ARCHIVE_THRESHOLD), 'NULL')||' as DAYS_FOR_ARCHIVE_THRESHOLD
|
||||||
|
,systimestamp as CREATED
|
||||||
|
from tmp_gr t
|
||||||
|
join (SELECT * from DBMS_CLOUD.LIST_OBJECTS(
|
||||||
|
credential_name => '''||CT_MRDS.ENV_MANAGER.gvCredentialName||''',
|
||||||
|
location_uri => '''||vOdsBucketUri||'''
|
||||||
|
)
|
||||||
|
) r
|
||||||
|
on t.filename = r.object_name'
|
||||||
|
;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('vQuery','DEBUG',vQuery);
|
||||||
|
execute immediate vQuery into vStats;
|
||||||
|
|
||||||
|
vStats.A_TABLE_STAT_KEY := CT_MRDS.A_TABLE_STAT_KEY_SEQ.NEXTVAL;
|
||||||
|
insert into CT_MRDS.A_TABLE_STAT_HIST values vStats;
|
||||||
|
delete from CT_MRDS.A_TABLE_STAT where A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey;
|
||||||
|
insert into CT_MRDS.A_TABLE_STAT values vStats;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_UNKNOWN, CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE));
|
||||||
|
END GATHER_TABLE_STAT;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-- TRASH FOLDER MANAGEMENT PROCEDURES
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PROCEDURE RESTORE_FILE_FROM_TRASH (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pRestoreAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
)
|
||||||
|
IS
|
||||||
|
vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE;
|
||||||
|
vSourceFileReceived CT_MRDS.A_SOURCE_FILE_RECEIVED%ROWTYPE;
|
||||||
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
|
vTrashPath VARCHAR2(1000);
|
||||||
|
vOdsPath VARCHAR2(1000);
|
||||||
|
vFilesRestored PLS_INTEGER := 0;
|
||||||
|
vFilesUpdated PLS_INTEGER := 0;
|
||||||
|
vRestoreLevel VARCHAR2(50);
|
||||||
|
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
||||||
|
BEGIN
|
||||||
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
||||||
|
'pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey), 'NULL'),
|
||||||
|
'pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL'),
|
||||||
|
'pRestoreAll => '||CASE WHEN pRestoreAll THEN 'TRUE' ELSE 'FALSE' END
|
||||||
|
));
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
|
||||||
|
-- Determine restore level (priority: LEVEL 3 > LEVEL 2 > LEVEL 1)
|
||||||
|
IF pSourceFileReceivedKey IS NOT NULL THEN
|
||||||
|
vRestoreLevel := 'LEVEL_3_SINGLE_FILE';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Restore level: LEVEL 3 - Single file restoration','INFO', 'A_SOURCE_FILE_RECEIVED_KEY: ' || pSourceFileReceivedKey);
|
||||||
|
|
||||||
|
-- LEVEL 3: Restore single file by A_SOURCE_FILE_RECEIVED_KEY
|
||||||
|
BEGIN
|
||||||
|
SELECT *
|
||||||
|
INTO vSourceFileReceived
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE A_SOURCE_FILE_RECEIVED_KEY = pSourceFileReceivedKey
|
||||||
|
AND PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
|
||||||
|
vSourceFileConfig := CT_MRDS.FILE_MANAGER.GET_SOURCE_FILE_CONFIG(pSourceFileConfigKey => vSourceFileReceived.A_SOURCE_FILE_CONFIG_KEY);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN NO_DATA_FOUND THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20101, 'File not found or status is not ARCHIVED_AND_TRASHED for A_SOURCE_FILE_RECEIVED_KEY: ' || pSourceFileReceivedKey);
|
||||||
|
END;
|
||||||
|
|
||||||
|
vTrashPath := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'TRASH/' || vSourceFileConfig.A_SOURCE_KEY || '/' || vSourceFileConfig.TABLE_ID || '/' || vSourceFileReceived.SOURCE_FILE_NAME;
|
||||||
|
vOdsPath := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'ODS/' || vSourceFileConfig.A_SOURCE_KEY || '/' || vSourceFileConfig.TABLE_ID || '/' || vSourceFileReceived.SOURCE_FILE_NAME;
|
||||||
|
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Restoring single file from TRASH to ODS','INFO', 'Source: ' || vTrashPath || cgBL || 'Target: ' || vOdsPath);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.MOVE_OBJECT(
|
||||||
|
source_credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
source_object_uri => vTrashPath,
|
||||||
|
target_object_uri => vOdsPath,
|
||||||
|
target_credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName
|
||||||
|
);
|
||||||
|
vFilesRestored := 1;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('File successfully moved from TRASH to ODS','INFO', vSourceFileReceived.SOURCE_FILE_NAME);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to move file from TRASH to ODS','ERROR', vTrashPath);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(-20103, 'Failed to restore file from TRASH: ' || SQLERRM);
|
||||||
|
END;
|
||||||
|
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
SET PROCESSING_STATUS = 'INGESTED',
|
||||||
|
ARCH_PATH = NULL,
|
||||||
|
PARTITION_YEAR = NULL,
|
||||||
|
PARTITION_MONTH = NULL
|
||||||
|
WHERE A_SOURCE_FILE_RECEIVED_KEY = pSourceFileReceivedKey
|
||||||
|
AND PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
vFilesUpdated := SQL%ROWCOUNT;
|
||||||
|
|
||||||
|
ELSIF pSourceFileConfigKey IS NOT NULL THEN
|
||||||
|
vRestoreLevel := 'LEVEL_2_CONFIG_FILES';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Restore level: LEVEL 2 - Configuration-based restoration','INFO', 'pSourceFileConfigKey: ' || pSourceFileConfigKey);
|
||||||
|
|
||||||
|
-- LEVEL 2: Restore all files for specific pSourceFileConfigKey
|
||||||
|
vSourceFileConfig := CT_MRDS.FILE_MANAGER.GET_SOURCE_FILE_CONFIG(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
|
||||||
|
FOR file_rec IN (
|
||||||
|
SELECT A_SOURCE_FILE_RECEIVED_KEY, SOURCE_FILE_NAME
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey
|
||||||
|
AND PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED'
|
||||||
|
) LOOP
|
||||||
|
vTrashPath := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'TRASH/' || vSourceFileConfig.A_SOURCE_KEY || '/' || vSourceFileConfig.TABLE_ID || '/' || file_rec.SOURCE_FILE_NAME;
|
||||||
|
vOdsPath := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'ODS/' || vSourceFileConfig.A_SOURCE_KEY || '/' || vSourceFileConfig.TABLE_ID || '/' || file_rec.SOURCE_FILE_NAME;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.MOVE_OBJECT(
|
||||||
|
source_credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
source_object_uri => vTrashPath,
|
||||||
|
target_object_uri => vOdsPath,
|
||||||
|
target_credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName
|
||||||
|
);
|
||||||
|
vFilesRestored := vFilesRestored + 1;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('File restored from TRASH','DEBUG', file_rec.SOURCE_FILE_NAME);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to restore file from TRASH','ERROR', file_rec.SOURCE_FILE_NAME);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
SET PROCESSING_STATUS = 'INGESTED',
|
||||||
|
ARCH_PATH = NULL,
|
||||||
|
PARTITION_YEAR = NULL,
|
||||||
|
PARTITION_MONTH = NULL
|
||||||
|
WHERE A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey
|
||||||
|
AND PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
vFilesUpdated := SQL%ROWCOUNT;
|
||||||
|
|
||||||
|
ELSIF pRestoreAll THEN
|
||||||
|
vRestoreLevel := 'LEVEL_1_GLOBAL_RESTORE';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Restore level: LEVEL 1 - Global TRASH restoration','INFO', 'Restoring ALL files with ARCHIVED_AND_TRASHED status');
|
||||||
|
|
||||||
|
-- LEVEL 1: Restore all files with ARCHIVED_AND_TRASHED status across all configurations
|
||||||
|
FOR file_rec IN (
|
||||||
|
SELECT r.A_SOURCE_FILE_RECEIVED_KEY, r.SOURCE_FILE_NAME,
|
||||||
|
c.A_SOURCE_KEY, c.TABLE_ID
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
|
JOIN CT_MRDS.A_SOURCE_FILE_CONFIG c ON r.A_SOURCE_FILE_CONFIG_KEY = c.A_SOURCE_FILE_CONFIG_KEY
|
||||||
|
WHERE r.PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED'
|
||||||
|
) LOOP
|
||||||
|
vTrashPath := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'TRASH/' || file_rec.A_SOURCE_KEY || '/' || file_rec.TABLE_ID || '/' || file_rec.SOURCE_FILE_NAME;
|
||||||
|
vOdsPath := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'ODS/' || file_rec.A_SOURCE_KEY || '/' || file_rec.TABLE_ID || '/' || file_rec.SOURCE_FILE_NAME;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.MOVE_OBJECT(
|
||||||
|
source_credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
source_object_uri => vTrashPath,
|
||||||
|
target_object_uri => vOdsPath,
|
||||||
|
target_credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName
|
||||||
|
);
|
||||||
|
vFilesRestored := vFilesRestored + 1;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('File restored from TRASH','DEBUG', file_rec.SOURCE_FILE_NAME);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to restore file from TRASH','ERROR', file_rec.SOURCE_FILE_NAME);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
SET PROCESSING_STATUS = 'INGESTED',
|
||||||
|
ARCH_PATH = NULL,
|
||||||
|
PARTITION_YEAR = NULL,
|
||||||
|
PARTITION_MONTH = NULL
|
||||||
|
WHERE PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
vFilesUpdated := SQL%ROWCOUNT;
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
RAISE_APPLICATION_ERROR(-20104, 'No restore level specified. Provide pSourceFileReceivedKey, pSourceFileConfigKey, or set pRestoreAll=TRUE');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Total files restored from TRASH: ' || vFilesRestored,'INFO');
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Total file records updated to INGESTED: ' || vFilesUpdated,'INFO');
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('TRASH restoration completed successfully','INFO', 'Level: ' || vRestoreLevel || ', Files restored: ' || vFilesRestored || ', Records updated: ' || vFilesUpdated);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO', vParameters);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
ROLLBACK;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_UNKNOWN, CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE));
|
||||||
|
END RESTORE_FILE_FROM_TRASH;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PROCEDURE PURGE_TRASH_FOLDER (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pPurgeAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
)
|
||||||
|
IS
|
||||||
|
vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE;
|
||||||
|
vSourceFileReceived CT_MRDS.A_SOURCE_FILE_RECEIVED%ROWTYPE;
|
||||||
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
|
vTrashLocationUri VARCHAR2(1000);
|
||||||
|
vFilesDeleted PLS_INTEGER := 0;
|
||||||
|
vFilesUpdated PLS_INTEGER := 0;
|
||||||
|
vPurgeLevel VARCHAR2(50);
|
||||||
|
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
||||||
|
BEGIN
|
||||||
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
||||||
|
'pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey), 'NULL'),
|
||||||
|
'pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL'),
|
||||||
|
'pPurgeAll => '||CASE WHEN pPurgeAll THEN 'TRUE' ELSE 'FALSE' END
|
||||||
|
));
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
|
||||||
|
-- Determine purge level (priority: LEVEL 3 > LEVEL 2 > LEVEL 1)
|
||||||
|
IF pSourceFileReceivedKey IS NOT NULL THEN
|
||||||
|
vPurgeLevel := 'LEVEL_3_SINGLE_FILE';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Purge level: LEVEL 3 - Single file deletion','INFO', 'A_SOURCE_FILE_RECEIVED_KEY: ' || pSourceFileReceivedKey);
|
||||||
|
|
||||||
|
-- LEVEL 3: Delete single file by A_SOURCE_FILE_RECEIVED_KEY
|
||||||
|
BEGIN
|
||||||
|
SELECT *
|
||||||
|
INTO vSourceFileReceived
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE A_SOURCE_FILE_RECEIVED_KEY = pSourceFileReceivedKey
|
||||||
|
AND PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
|
||||||
|
vSourceFileConfig := CT_MRDS.FILE_MANAGER.GET_SOURCE_FILE_CONFIG(pSourceFileConfigKey => vSourceFileReceived.A_SOURCE_FILE_CONFIG_KEY);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN NO_DATA_FOUND THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20301, 'File not found or status is not ARCHIVED_AND_TRASHED for A_SOURCE_FILE_RECEIVED_KEY: ' || pSourceFileReceivedKey);
|
||||||
|
END;
|
||||||
|
|
||||||
|
vTrashLocationUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'TRASH/' || vSourceFileConfig.A_SOURCE_KEY || '/' || vSourceFileConfig.TABLE_ID || '/' || vSourceFileReceived.SOURCE_FILE_NAME;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.DELETE_OBJECT(
|
||||||
|
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
object_uri => vTrashLocationUri
|
||||||
|
);
|
||||||
|
vFilesDeleted := 1;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Single file deleted from TRASH','INFO', vSourceFileReceived.SOURCE_FILE_NAME);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to delete file from TRASH','ERROR', vTrashLocationUri);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(-20302, 'Failed to delete single file from TRASH: ' || SQLERRM);
|
||||||
|
END;
|
||||||
|
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
SET PROCESSING_STATUS = 'ARCHIVED_AND_PURGED'
|
||||||
|
WHERE A_SOURCE_FILE_RECEIVED_KEY = pSourceFileReceivedKey
|
||||||
|
AND PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
vFilesUpdated := SQL%ROWCOUNT;
|
||||||
|
|
||||||
|
ELSIF pSourceFileConfigKey IS NOT NULL THEN
|
||||||
|
vPurgeLevel := 'LEVEL_2_CONFIG_FILES';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Purge level: LEVEL 2 - Configuration-based deletion','INFO', 'pSourceFileConfigKey: ' || pSourceFileConfigKey);
|
||||||
|
|
||||||
|
-- LEVEL 2: Delete all files for specific pSourceFileConfigKey
|
||||||
|
vSourceFileConfig := CT_MRDS.FILE_MANAGER.GET_SOURCE_FILE_CONFIG(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
vTrashLocationUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'TRASH/' || vSourceFileConfig.A_SOURCE_KEY || '/' || vSourceFileConfig.TABLE_ID || '/';
|
||||||
|
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Purging TRASH folder for configuration','INFO', 'Location: ' || vTrashLocationUri);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
FOR trash_file IN (
|
||||||
|
SELECT object_name
|
||||||
|
FROM DBMS_CLOUD.LIST_OBJECTS(
|
||||||
|
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
location_uri => vTrashLocationUri
|
||||||
|
)
|
||||||
|
) LOOP
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.DELETE_OBJECT(
|
||||||
|
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
object_uri => vTrashLocationUri || trash_file.object_name
|
||||||
|
);
|
||||||
|
vFilesDeleted := vFilesDeleted + 1;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('File deleted from TRASH','DEBUG', trash_file.object_name);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to delete file from TRASH','ERROR', trash_file.object_name);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to list or delete TRASH files','ERROR', vTrashLocationUri);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(-20303, 'Failed to purge TRASH folder for configuration: ' || SQLERRM);
|
||||||
|
END;
|
||||||
|
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
SET PROCESSING_STATUS = 'ARCHIVED_AND_PURGED'
|
||||||
|
WHERE A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey
|
||||||
|
AND PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
vFilesUpdated := SQL%ROWCOUNT;
|
||||||
|
|
||||||
|
ELSIF pPurgeAll THEN
|
||||||
|
vPurgeLevel := 'LEVEL_1_GLOBAL_PURGE';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Purge level: LEVEL 1 - Global TRASH purge','INFO', 'Deleting ALL files with ARCHIVED_AND_TRASHED status');
|
||||||
|
|
||||||
|
-- LEVEL 1: Delete all files with ARCHIVED_AND_TRASHED status across all configurations
|
||||||
|
FOR config_rec IN (
|
||||||
|
SELECT DISTINCT c.A_SOURCE_FILE_CONFIG_KEY, c.A_SOURCE_KEY, c.TABLE_ID
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG c
|
||||||
|
JOIN CT_MRDS.A_SOURCE_FILE_RECEIVED r ON r.A_SOURCE_FILE_CONFIG_KEY = c.A_SOURCE_FILE_CONFIG_KEY
|
||||||
|
WHERE r.PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED'
|
||||||
|
) LOOP
|
||||||
|
vTrashLocationUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'TRASH/' || config_rec.A_SOURCE_KEY || '/' || config_rec.TABLE_ID || '/';
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Processing TRASH location','DEBUG', vTrashLocationUri);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
FOR trash_file IN (
|
||||||
|
SELECT object_name
|
||||||
|
FROM DBMS_CLOUD.LIST_OBJECTS(
|
||||||
|
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
location_uri => vTrashLocationUri
|
||||||
|
)
|
||||||
|
) LOOP
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.DELETE_OBJECT(
|
||||||
|
credential_name => CT_MRDS.ENV_MANAGER.gvCredentialName,
|
||||||
|
object_uri => vTrashLocationUri || trash_file.object_name
|
||||||
|
);
|
||||||
|
vFilesDeleted := vFilesDeleted + 1;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('File deleted from TRASH','DEBUG', trash_file.object_name);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to delete file from TRASH','ERROR', trash_file.object_name);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Failed to list TRASH files','WARNING', vTrashLocationUri || ' - ' || SQLERRM);
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
SET PROCESSING_STATUS = 'ARCHIVED_AND_PURGED'
|
||||||
|
WHERE PROCESSING_STATUS = 'ARCHIVED_AND_TRASHED';
|
||||||
|
vFilesUpdated := SQL%ROWCOUNT;
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
RAISE_APPLICATION_ERROR(-20304, 'No purge level specified. Provide pSourceFileReceivedKey, pSourceFileConfigKey, or set pPurgeAll=TRUE');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Total files deleted from TRASH: ' || vFilesDeleted,'INFO');
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Total file records updated to ARCHIVED_AND_PURGED: ' || vFilesUpdated,'INFO');
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('TRASH folder purge completed successfully','INFO', 'Level: ' || vPurgeLevel || ', Files deleted: ' || vFilesDeleted || ', Records updated: ' || vFilesUpdated);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO', vParameters);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
ROLLBACK;
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters);
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RAISE_APPLICATION_ERROR(CT_MRDS.ENV_MANAGER.CODE_UNKNOWN, CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE));
|
||||||
|
END PURGE_TRASH_FOLDER;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FUNCTION PURGE_TRASH_FOLDER (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pPurgeAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
) RETURN PLS_INTEGER
|
||||||
|
IS
|
||||||
|
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||||
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
|
BEGIN
|
||||||
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
||||||
|
'pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey), 'NULL'),
|
||||||
|
'pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL'),
|
||||||
|
'pPurgeAll => '||CASE WHEN pPurgeAll THEN 'TRUE' ELSE 'FALSE' END
|
||||||
|
));
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
----
|
||||||
|
PURGE_TRASH_FOLDER(
|
||||||
|
pSourceFileReceivedKey => pSourceFileReceivedKey,
|
||||||
|
pSourceFileConfigKey => pSourceFileConfigKey,
|
||||||
|
pPurgeAll => pPurgeAll
|
||||||
|
);
|
||||||
|
----
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
END PURGE_TRASH_FOLDER;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FUNCTION RESTORE_FILE_FROM_TRASH (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pRestoreAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
) RETURN PLS_INTEGER
|
||||||
|
IS
|
||||||
|
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||||
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
|
BEGIN
|
||||||
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
||||||
|
'pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey), 'NULL'),
|
||||||
|
'pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL'),
|
||||||
|
'pRestoreAll => '||CASE WHEN pRestoreAll THEN 'TRUE' ELSE 'FALSE' END
|
||||||
|
));
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
----
|
||||||
|
RESTORE_FILE_FROM_TRASH(
|
||||||
|
pSourceFileReceivedKey => pSourceFileReceivedKey,
|
||||||
|
pSourceFileConfigKey => pSourceFileConfigKey,
|
||||||
|
pRestoreAll => pRestoreAll
|
||||||
|
);
|
||||||
|
----
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
END RESTORE_FILE_FROM_TRASH;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-- PACKAGE VERSION MANAGEMENT FUNCTIONS IMPLEMENTATION
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FUNCTION GET_VERSION
|
||||||
|
RETURN VARCHAR2
|
||||||
|
IS
|
||||||
|
BEGIN
|
||||||
|
RETURN PACKAGE_VERSION;
|
||||||
|
END GET_VERSION;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FUNCTION GET_BUILD_INFO
|
||||||
|
RETURN VARCHAR2
|
||||||
|
IS
|
||||||
|
BEGIN
|
||||||
|
RETURN CT_MRDS.ENV_MANAGER.GET_PACKAGE_VERSION_INFO(
|
||||||
|
pPackageName => 'FILE_ARCHIVER',
|
||||||
|
pVersion => PACKAGE_VERSION,
|
||||||
|
pBuildDate => PACKAGE_BUILD_DATE,
|
||||||
|
pAuthor => PACKAGE_AUTHOR
|
||||||
|
);
|
||||||
|
END GET_BUILD_INFO;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FUNCTION GET_VERSION_HISTORY
|
||||||
|
RETURN VARCHAR2
|
||||||
|
IS
|
||||||
|
BEGIN
|
||||||
|
RETURN CT_MRDS.ENV_MANAGER.FORMAT_VERSION_HISTORY(
|
||||||
|
pPackageName => 'FILE_ARCHIVER',
|
||||||
|
pVersionHistory => VERSION_HISTORY
|
||||||
|
);
|
||||||
|
END GET_VERSION_HISTORY;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FUNCTION ARCHIVE_TABLE_DATA (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE,
|
||||||
|
pKeepInTrash IN BOOLEAN DEFAULT TRUE
|
||||||
|
) RETURN PLS_INTEGER
|
||||||
|
IS
|
||||||
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
|
BEGIN
|
||||||
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
||||||
|
'pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL'),
|
||||||
|
'pKeepInTrash => '||CASE WHEN pKeepInTrash THEN 'TRUE' ELSE 'FALSE' END
|
||||||
|
));
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
----
|
||||||
|
ARCHIVE_TABLE_DATA(pSourceFileConfigKey => pSourceFileConfigKey, pKeepInTrash => pKeepInTrash);
|
||||||
|
----
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
END ARCHIVE_TABLE_DATA;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FUNCTION GATHER_TABLE_STAT (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
||||||
|
) RETURN PLS_INTEGER
|
||||||
|
IS
|
||||||
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
|
BEGIN
|
||||||
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL')));
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
----
|
||||||
|
GATHER_TABLE_STAT(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
----
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT(CT_MRDS.ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
END GATHER_TABLE_STAT;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
END;
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
create or replace PACKAGE CT_MRDS.FILE_ARCHIVER
|
||||||
|
AUTHID CURRENT_USER
|
||||||
|
AS
|
||||||
|
/**
|
||||||
|
* General comment for package: Please put comments for functions and procedures as shown in below example.
|
||||||
|
* It is a standard.
|
||||||
|
* The structure of comment is used by GET_PACKAGE_DOCUMENTATION function
|
||||||
|
* which returns documentation text for confluence page (to Copy-Paste it).
|
||||||
|
**/
|
||||||
|
|
||||||
|
-- Example comment:
|
||||||
|
/**
|
||||||
|
* @name EX_PROCEDURE_NAME
|
||||||
|
* @desc Procedure description
|
||||||
|
* @example select LOGGING_AND_ERROR_MANAGER.EX_PROCEDURE_NAME(pParameter => 129) from dual;
|
||||||
|
* @ex_rslt Example Result
|
||||||
|
**/
|
||||||
|
|
||||||
|
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
||||||
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.2.1';
|
||||||
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-10 09:00:00';
|
||||||
|
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski';
|
||||||
|
|
||||||
|
-- Version History (Latest changes first)
|
||||||
|
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
||||||
|
'3.2.1 (2026-02-10): Fixed status update - ARCHIVED → ARCHIVED_AND_TRASHED when moving files to TRASH folder (critical bug fix)' || CHR(13)||CHR(10) ||
|
||||||
|
'3.2.0 (2026-02-06): Added pKeepInTrash parameter (DEFAULT TRUE) to ARCHIVE_TABLE_DATA for TRASH folder retention control - files kept in TRASH subfolder (DATA bucket) by default for safety and compliance' || CHR(13)||CHR(10) ||
|
||||||
|
'3.1.2 (2026-02-06): Fixed missing PARTITION_YEAR/PARTITION_MONTH assignments in UPDATE statement and export query circular dependency (now filters by workflow_start instead of partition fields)' || CHR(13)||CHR(10) ||
|
||||||
|
'3.1.1 (2026-02-06): Fixed ORA-01422 error when DBMS_CLOUD.EXPORT_DATA creates multiple parquet files (parallel execution). Now stores archive directory prefix instead of individual filenames' || CHR(13)||CHR(10) ||
|
||||||
|
'3.1.0 (2026-01-29): Added function overloads for ARCHIVE_TABLE_DATA and GATHER_TABLE_STAT returning SQLCODE for Python library integration' || CHR(13)||CHR(10) ||
|
||||||
|
'3.0.0 (2026-01-27): MARS-828 - Added flexible archival strategies (MINIMUM_AGE_MONTHS with 0=current month, HYBRID) via ARCHIVAL_STRATEGY configuration' || CHR(13)||CHR(10) ||
|
||||||
|
'2.0.0 (2025-10-22): Added package versioning system using centralized ENV_MANAGER functions' || CHR(13)||CHR(10) ||
|
||||||
|
'1.5.0 (2025-10-18): Enhanced ARCHIVE_TABLE_DATA with Hive-style partitioning support' || CHR(13)||CHR(10) ||
|
||||||
|
'1.0.0 (2025-09-15): Initial release with table archival and statistics gathering';
|
||||||
|
|
||||||
|
cgBL CONSTANT VARCHAR2(2) := ENV_MANAGER.cgBL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ARCHIVE_TABLE_DATA
|
||||||
|
* @desc Wrapper procedure for DBMS_CLOUD.EXPORT_DATA.
|
||||||
|
* Exports data from table specified by pSourceFileConfigKey(A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY) into PARQUET file on OCI infrustructure.
|
||||||
|
* Each YEAR_MONTH pair goes to seperate file (implicit partitioning).
|
||||||
|
* @param pKeepInTrash - When TRUE (default), files are kept in TRASH folder (DATA bucket subfolder) for safety. When FALSE, files are deleted from TRASH after successful archive.
|
||||||
|
**/
|
||||||
|
PROCEDURE ARCHIVE_TABLE_DATA (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE,
|
||||||
|
pKeepInTrash IN BOOLEAN DEFAULT TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ARCHIVE_TABLE_DATA
|
||||||
|
* @desc Function overload for ARCHIVE_TABLE_DATA procedure.
|
||||||
|
* Returns SQLCODE for Python library integration.
|
||||||
|
* Calls the main ARCHIVE_TABLE_DATA procedure and captures execution result.
|
||||||
|
* @param pKeepInTrash - When TRUE (default), files are kept in TRASH folder (DATA bucket subfolder) for safety. When FALSE, files are deleted from TRASH after successful archive.
|
||||||
|
* @example SELECT FILE_ARCHIVER.ARCHIVE_TABLE_DATA(pSourceFileConfigKey => 123) FROM DUAL;
|
||||||
|
* @ex_rslt 0 (success) or error code
|
||||||
|
**/
|
||||||
|
FUNCTION ARCHIVE_TABLE_DATA (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE,
|
||||||
|
pKeepInTrash IN BOOLEAN DEFAULT TRUE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GATHER_TABLE_STAT
|
||||||
|
* @desc Gather info about EXTERNAL TABLE specified by pSourceFileConfigKey parameter (A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY).
|
||||||
|
* Data is inserted into A_TABLE_STAT and A_TABLE_STAT_HIST.
|
||||||
|
**/
|
||||||
|
PROCEDURE GATHER_TABLE_STAT (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GATHER_TABLE_STAT
|
||||||
|
* @desc Function overload for GATHER_TABLE_STAT procedure.
|
||||||
|
* Returns SQLCODE for Python library integration.
|
||||||
|
* Calls the main GATHER_TABLE_STAT procedure and captures execution result.
|
||||||
|
* @example SELECT FILE_ARCHIVER.GATHER_TABLE_STAT(pSourceFileConfigKey => 123) FROM DUAL;
|
||||||
|
* @ex_rslt 0 (success) or error code
|
||||||
|
**/
|
||||||
|
FUNCTION GATHER_TABLE_STAT (
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name RESTORE_FILE_FROM_TRASH
|
||||||
|
* @desc Restores files from TRASH folder back to ODS at three different granularity levels.
|
||||||
|
* Moves files from TRASH subfolder back to ODS subfolder in DATA bucket.
|
||||||
|
* Updates status from ARCHIVED_AND_TRASHED to INGESTED and clears archival metadata.
|
||||||
|
* @param pSourceFileReceivedKey - (LEVEL 3) Specific file to restore by A_SOURCE_FILE_RECEIVED_KEY (highest priority)
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 2) Restore all files for specific configuration key (medium priority)
|
||||||
|
* @param pRestoreAll - (LEVEL 1) When TRUE, restore ALL files with ARCHIVED_AND_TRASHED status (lowest priority)
|
||||||
|
* @example -- Restore single file: CALL FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pSourceFileReceivedKey => 12345);
|
||||||
|
* @example -- Restore all files for config: CALL FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pSourceFileConfigKey => 341);
|
||||||
|
* @example -- Restore all TRASH globally: CALL FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pRestoreAll => TRUE);
|
||||||
|
**/
|
||||||
|
PROCEDURE RESTORE_FILE_FROM_TRASH (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pRestoreAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name RESTORE_FILE_FROM_TRASH
|
||||||
|
* @desc Function overload for RESTORE_FILE_FROM_TRASH procedure.
|
||||||
|
* Returns SQLCODE for Python library integration.
|
||||||
|
* Calls the main RESTORE_FILE_FROM_TRASH procedure and captures execution result.
|
||||||
|
* @param pSourceFileReceivedKey - (LEVEL 3) Specific file to restore by A_SOURCE_FILE_RECEIVED_KEY (highest priority)
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 2) Restore all files for specific configuration key (medium priority)
|
||||||
|
* @param pRestoreAll - (LEVEL 1) When TRUE, restore ALL files with ARCHIVED_AND_TRASHED status (lowest priority)
|
||||||
|
* @example SELECT FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pSourceFileReceivedKey => 12345) FROM DUAL;
|
||||||
|
* @ex_rslt 0 (success) or error code
|
||||||
|
**/
|
||||||
|
FUNCTION RESTORE_FILE_FROM_TRASH (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pRestoreAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name PURGE_TRASH_FOLDER
|
||||||
|
* @desc Deletes files from TRASH folder at three different granularity levels.
|
||||||
|
* Updates status from ARCHIVED_AND_TRASHED to ARCHIVED_AND_PURGED for all affected files.
|
||||||
|
* WARNING: This operation is irreversible - files are permanently deleted from TRASH.
|
||||||
|
* @param pSourceFileReceivedKey - (LEVEL 3) Specific file to delete by A_SOURCE_FILE_RECEIVED_KEY (highest priority)
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 2) Delete all files for specific configuration key (medium priority)
|
||||||
|
* @param pPurgeAll - (LEVEL 1) When TRUE, delete ALL files with ARCHIVED_AND_TRASHED status (lowest priority)
|
||||||
|
* @example -- Delete single file: CALL FILE_ARCHIVER.PURGE_TRASH_FOLDER(pSourceFileReceivedKey => 12345);
|
||||||
|
* @example -- Delete all files for config: CALL FILE_ARCHIVER.PURGE_TRASH_FOLDER(pSourceFileConfigKey => 341);
|
||||||
|
* @example -- Delete all TRASH globally: CALL FILE_ARCHIVER.PURGE_TRASH_FOLDER(pPurgeAll => TRUE);
|
||||||
|
**/
|
||||||
|
PROCEDURE PURGE_TRASH_FOLDER (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pPurgeAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name PURGE_TRASH_FOLDER
|
||||||
|
* @desc Function overload for PURGE_TRASH_FOLDER procedure.
|
||||||
|
* Returns SQLCODE for Python library integration.
|
||||||
|
* Calls the main PURGE_TRASH_FOLDER procedure and captures execution result.
|
||||||
|
* WARNING: This operation is irreversible - files are permanently deleted from TRASH.
|
||||||
|
* @param pSourceFileReceivedKey - (LEVEL 3) Specific file to delete by A_SOURCE_FILE_RECEIVED_KEY (highest priority)
|
||||||
|
* @param pSourceFileConfigKey - (LEVEL 2) Delete all files for specific configuration key (medium priority)
|
||||||
|
* @param pPurgeAll - (LEVEL 1) When TRUE, delete ALL files with ARCHIVED_AND_TRASHED status (lowest priority)
|
||||||
|
* @example SELECT FILE_ARCHIVER.PURGE_TRASH_FOLDER(pSourceFileReceivedKey => 12345) FROM DUAL;
|
||||||
|
* @ex_rslt 0 (success) or error code
|
||||||
|
**/
|
||||||
|
FUNCTION PURGE_TRASH_FOLDER (
|
||||||
|
pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL,
|
||||||
|
pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL,
|
||||||
|
pPurgeAll IN BOOLEAN DEFAULT FALSE
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- PACKAGE VERSION MANAGEMENT FUNCTIONS
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_VERSION
|
||||||
|
* @desc Returns the current version number of the FILE_ARCHIVER package.
|
||||||
|
* Uses semantic versioning format (MAJOR.MINOR.PATCH).
|
||||||
|
* @example SELECT FILE_ARCHIVER.GET_VERSION() FROM DUAL;
|
||||||
|
* @ex_rslt 2.0.0
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_BUILD_INFO
|
||||||
|
* @desc Returns comprehensive build information including version, build date, and author.
|
||||||
|
* Uses centralized ENV_MANAGER.GET_PACKAGE_VERSION_INFO function.
|
||||||
|
* @example SELECT FILE_ARCHIVER.GET_BUILD_INFO() FROM DUAL;
|
||||||
|
* @ex_rslt Package: FILE_ARCHIVER
|
||||||
|
* Version: 2.0.0
|
||||||
|
* Build Date: 2025-10-22 16:45:00
|
||||||
|
* Author: Grzegorz Michalski
|
||||||
|
**/
|
||||||
|
FUNCTION GET_BUILD_INFO RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_VERSION_HISTORY
|
||||||
|
* @desc Returns complete version history with all releases and changes.
|
||||||
|
* Uses centralized ENV_MANAGER.FORMAT_VERSION_HISTORY function.
|
||||||
|
* @example SELECT FILE_ARCHIVER.GET_VERSION_HISTORY() FROM DUAL;
|
||||||
|
* @ex_rslt FILE_ARCHIVER Version History:
|
||||||
|
* 2.0.0 (2025-10-22): Added package versioning system...
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2;
|
||||||
|
|
||||||
|
END;
|
||||||
|
|
||||||
|
/
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
-- MARS-828: Test archival strategies
|
|
||||||
-- Author: Grzegorz Michalski
|
|
||||||
-- Date: 2026-01-27
|
|
||||||
-- Description: Comprehensive test scenarios for all archival strategies
|
|
||||||
|
|
||||||
SET SERVEROUTPUT ON SIZE UNLIMITED
|
|
||||||
|
|
||||||
PROMPT ========================================
|
|
||||||
PROMPT MARS-828: Testing Archival Strategies
|
|
||||||
PROMPT ========================================
|
|
||||||
|
|
||||||
-- Test 1: THRESHOLD_BASED (backward compatibility)
|
|
||||||
PROMPT
|
|
||||||
PROMPT Test 1: THRESHOLD_BASED strategy
|
|
||||||
DECLARE
|
|
||||||
vTestKey NUMBER := -1000;
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO CT_MRDS.A_SOURCE_FILE_CONFIG (
|
|
||||||
A_SOURCE_FILE_CONFIG_KEY,
|
|
||||||
A_SOURCE_KEY,
|
|
||||||
SOURCE_FILE_TYPE,
|
|
||||||
SOURCE_FILE_ID,
|
|
||||||
SOURCE_FILE_DESC,
|
|
||||||
SOURCE_FILE_NAME_PATTERN,
|
|
||||||
TABLE_ID,
|
|
||||||
TEMPLATE_TABLE_NAME,
|
|
||||||
ARCHIVAL_STRATEGY,
|
|
||||||
DAYS_FOR_ARCHIVE_THRESHOLD
|
|
||||||
) VALUES (
|
|
||||||
vTestKey,
|
|
||||||
'TEST1',
|
|
||||||
'INPUT',
|
|
||||||
'TEST_THRESHOLD',
|
|
||||||
'Test threshold-based',
|
|
||||||
'test*.csv',
|
|
||||||
'TEST_TABLE',
|
|
||||||
'CT_ET_TEMPLATES.TEST',
|
|
||||||
'THRESHOLD_BASED',
|
|
||||||
30
|
|
||||||
);
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: THRESHOLD_BASED strategy configured');
|
|
||||||
ROLLBACK;
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('FAILED: ' || SQLERRM);
|
|
||||||
ROLLBACK;
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Test 2: CURRENT_MONTH_ONLY
|
|
||||||
PROMPT
|
|
||||||
PROMPT Test 2: CURRENT_MONTH_ONLY strategy
|
|
||||||
DECLARE
|
|
||||||
vTestKey NUMBER := -1001;
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO CT_MRDS.A_SOURCE_FILE_CONFIG (
|
|
||||||
A_SOURCE_FILE_CONFIG_KEY,
|
|
||||||
A_SOURCE_KEY,
|
|
||||||
SOURCE_FILE_TYPE,
|
|
||||||
SOURCE_FILE_ID,
|
|
||||||
SOURCE_FILE_DESC,
|
|
||||||
SOURCE_FILE_NAME_PATTERN,
|
|
||||||
TABLE_ID,
|
|
||||||
TEMPLATE_TABLE_NAME,
|
|
||||||
ARCHIVAL_STRATEGY
|
|
||||||
) VALUES (
|
|
||||||
vTestKey,
|
|
||||||
'TEST2',
|
|
||||||
'INPUT',
|
|
||||||
'TEST_CURRENT_MONTH',
|
|
||||||
'Test current month only',
|
|
||||||
'test*.csv',
|
|
||||||
'TEST_TABLE',
|
|
||||||
'CT_ET_TEMPLATES.TEST',
|
|
||||||
'CURRENT_MONTH_ONLY'
|
|
||||||
);
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: CURRENT_MONTH_ONLY strategy configured');
|
|
||||||
ROLLBACK;
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('FAILED: ' || SQLERRM);
|
|
||||||
ROLLBACK;
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Test 3: MINIMUM_AGE_MONTHS (should succeed)
|
|
||||||
PROMPT
|
|
||||||
PROMPT Test 3: MINIMUM_AGE_MONTHS strategy with valid config
|
|
||||||
DECLARE
|
|
||||||
vTestKey NUMBER := -1002;
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO CT_MRDS.A_SOURCE_FILE_CONFIG (
|
|
||||||
A_SOURCE_FILE_CONFIG_KEY,
|
|
||||||
A_SOURCE_KEY,
|
|
||||||
SOURCE_FILE_TYPE,
|
|
||||||
SOURCE_FILE_ID,
|
|
||||||
SOURCE_FILE_DESC,
|
|
||||||
SOURCE_FILE_NAME_PATTERN,
|
|
||||||
TABLE_ID,
|
|
||||||
TEMPLATE_TABLE_NAME,
|
|
||||||
ARCHIVAL_STRATEGY,
|
|
||||||
MINIMUM_AGE_MONTHS
|
|
||||||
) VALUES (
|
|
||||||
vTestKey,
|
|
||||||
'TEST3',
|
|
||||||
'INPUT',
|
|
||||||
'TEST_MIN_AGE',
|
|
||||||
'Test minimum age months',
|
|
||||||
'test*.csv',
|
|
||||||
'TEST_TABLE',
|
|
||||||
'CT_ET_TEMPLATES.TEST',
|
|
||||||
'MINIMUM_AGE_MONTHS',
|
|
||||||
6
|
|
||||||
);
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: MINIMUM_AGE_MONTHS strategy configured with 6 months');
|
|
||||||
ROLLBACK;
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('FAILED: ' || SQLERRM);
|
|
||||||
ROLLBACK;
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Test 4: MINIMUM_AGE_MONTHS without value (should fail)
|
|
||||||
PROMPT
|
|
||||||
PROMPT Test 4: MINIMUM_AGE_MONTHS strategy without value (should fail)
|
|
||||||
DECLARE
|
|
||||||
vTestKey NUMBER := -1003;
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO CT_MRDS.A_SOURCE_FILE_CONFIG (
|
|
||||||
A_SOURCE_FILE_CONFIG_KEY,
|
|
||||||
A_SOURCE_KEY,
|
|
||||||
SOURCE_FILE_TYPE,
|
|
||||||
SOURCE_FILE_ID,
|
|
||||||
SOURCE_FILE_DESC,
|
|
||||||
SOURCE_FILE_NAME_PATTERN,
|
|
||||||
TABLE_ID,
|
|
||||||
TEMPLATE_TABLE_NAME,
|
|
||||||
ARCHIVAL_STRATEGY,
|
|
||||||
MINIMUM_AGE_MONTHS
|
|
||||||
) VALUES (
|
|
||||||
vTestKey,
|
|
||||||
'TEST4',
|
|
||||||
'INPUT',
|
|
||||||
'TEST_MIN_AGE_FAIL',
|
|
||||||
'Test minimum age months failure',
|
|
||||||
'test*.csv',
|
|
||||||
'TEST_TABLE',
|
|
||||||
'CT_ET_TEMPLATES.TEST',
|
|
||||||
'MINIMUM_AGE_MONTHS',
|
|
||||||
NULL -- Should trigger error
|
|
||||||
);
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('FAILED: Trigger did not fire - this should have failed!');
|
|
||||||
ROLLBACK;
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
IF SQLCODE = -20999 THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: Trigger correctly prevented invalid config');
|
|
||||||
ELSE
|
|
||||||
DBMS_OUTPUT.PUT_LINE('FAILED: Unexpected error: ' || SQLERRM);
|
|
||||||
END IF;
|
|
||||||
ROLLBACK;
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Test 5: HYBRID strategy
|
|
||||||
PROMPT
|
|
||||||
PROMPT Test 5: HYBRID strategy
|
|
||||||
DECLARE
|
|
||||||
vTestKey NUMBER := -1004;
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO CT_MRDS.A_SOURCE_FILE_CONFIG (
|
|
||||||
A_SOURCE_FILE_CONFIG_KEY,
|
|
||||||
A_SOURCE_KEY,
|
|
||||||
SOURCE_FILE_TYPE,
|
|
||||||
SOURCE_FILE_ID,
|
|
||||||
SOURCE_FILE_DESC,
|
|
||||||
SOURCE_FILE_NAME_PATTERN,
|
|
||||||
TABLE_ID,
|
|
||||||
TEMPLATE_TABLE_NAME,
|
|
||||||
ARCHIVAL_STRATEGY,
|
|
||||||
MINIMUM_AGE_MONTHS
|
|
||||||
) VALUES (
|
|
||||||
vTestKey,
|
|
||||||
'TEST5',
|
|
||||||
'INPUT',
|
|
||||||
'TEST_HYBRID',
|
|
||||||
'Test hybrid strategy',
|
|
||||||
'test*.csv',
|
|
||||||
'TEST_TABLE',
|
|
||||||
'CT_ET_TEMPLATES.TEST',
|
|
||||||
'HYBRID',
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: HYBRID strategy configured');
|
|
||||||
ROLLBACK;
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('FAILED: ' || SQLERRM);
|
|
||||||
ROLLBACK;
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Test 6: Invalid strategy (should fail)
|
|
||||||
PROMPT
|
|
||||||
PROMPT Test 6: Invalid strategy (should fail)
|
|
||||||
DECLARE
|
|
||||||
vTestKey NUMBER := -1005;
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO CT_MRDS.A_SOURCE_FILE_CONFIG (
|
|
||||||
A_SOURCE_FILE_CONFIG_KEY,
|
|
||||||
A_SOURCE_KEY,
|
|
||||||
SOURCE_FILE_TYPE,
|
|
||||||
SOURCE_FILE_ID,
|
|
||||||
SOURCE_FILE_DESC,
|
|
||||||
SOURCE_FILE_NAME_PATTERN,
|
|
||||||
TABLE_ID,
|
|
||||||
TEMPLATE_TABLE_NAME,
|
|
||||||
ARCHIVAL_STRATEGY
|
|
||||||
) VALUES (
|
|
||||||
vTestKey,
|
|
||||||
'TEST6',
|
|
||||||
'INPUT',
|
|
||||||
'TEST_INVALID',
|
|
||||||
'Test invalid strategy',
|
|
||||||
'test*.csv',
|
|
||||||
'TEST_TABLE',
|
|
||||||
'CT_ET_TEMPLATES.TEST',
|
|
||||||
'INVALID_STRATEGY'
|
|
||||||
);
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('FAILED: Check constraint did not fire!');
|
|
||||||
ROLLBACK;
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
IF SQLCODE = -2290 THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: Check constraint prevented invalid strategy');
|
|
||||||
ELSE
|
|
||||||
DBMS_OUTPUT.PUT_LINE('FAILED: Unexpected error: ' || SQLERRM);
|
|
||||||
END IF;
|
|
||||||
ROLLBACK;
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
PROMPT
|
|
||||||
PROMPT ========================================
|
|
||||||
PROMPT MARS-828: Testing Complete
|
|
||||||
PROMPT ========================================
|
|
||||||
@@ -29,7 +29,8 @@ DECLARE
|
|||||||
-- Format: 'SCHEMA.PACKAGE_NAME'
|
-- Format: 'SCHEMA.PACKAGE_NAME'
|
||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
vPackageList t_string_array := t_string_array(
|
vPackageList t_string_array := t_string_array(
|
||||||
'CT_MRDS.FILE_ARCHIVER'
|
'CT_MRDS.FILE_ARCHIVER',
|
||||||
|
'CT_MRDS.FILE_MANAGER'
|
||||||
);
|
);
|
||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- MARS-835-PREHOOK Installation Script 02: DATA_EXPORTER Package
|
-- MARS-835-PREHOOK Installation Script 02: DATA_EXPORTER Package
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- Purpose: Deploy updated DATA_EXPORTER package (SPEC + BODY) with parallel processing
|
-- Purpose: Deploy updated DATA_EXPORTER package (SPEC + BODY) v2.8.1
|
||||||
-- Schema: CT_MRDS
|
-- Schema: CT_MRDS
|
||||||
-- Object: PACKAGE DATA_EXPORTER
|
-- Object: PACKAGE DATA_EXPORTER
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON SIZE UNLIMITED
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
@@ -13,8 +14,8 @@ PROMPT =========================================================================
|
|||||||
PROMPT MARS-835-PREHOOK: Installing CT_MRDS.DATA_EXPORTER Package
|
PROMPT MARS-835-PREHOOK: Installing CT_MRDS.DATA_EXPORTER Package
|
||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
PROMPT Package: CT_MRDS.DATA_EXPORTER
|
PROMPT Package: CT_MRDS.DATA_EXPORTER
|
||||||
PROMPT Version: 2.2.0 -> 2.4.0 (MINOR)
|
PROMPT Version: 2.2.0 -> 2.8.1 (PATCH)
|
||||||
PROMPT Change: Added parallel processing + Smart Column Mapping for CSV exports
|
PROMPT Change: Fixed query in EXPORT_TABLE_DATA - removed A_LOAD_HISTORY join for single file
|
||||||
PROMPT ============================================================================
|
PROMPT ============================================================================
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
-- ====================================================================
|
||||||
|
-- MARS-835-PREHOOK: Update A_SOURCE_FILE_RECEIVED Table Structure
|
||||||
|
-- ====================================================================
|
||||||
|
-- Purpose:
|
||||||
|
-- 1. Rename column ARCH_FILE_NAME to ARCH_PATH
|
||||||
|
-- 2. Add new column PROCESS_NAME VARCHAR2(200)
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-13
|
||||||
|
-- ====================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
SET TIMING ON
|
||||||
|
|
||||||
|
PROMPT ====================================================================
|
||||||
|
PROMPT MARS-835-PREHOOK: Updating A_SOURCE_FILE_RECEIVED table structure
|
||||||
|
PROMPT ====================================================================
|
||||||
|
|
||||||
|
-- Check if column ARCH_FILE_NAME exists
|
||||||
|
DECLARE
|
||||||
|
v_column_exists NUMBER;
|
||||||
|
v_process_name_exists NUMBER;
|
||||||
|
BEGIN
|
||||||
|
-- Check if ARCH_FILE_NAME exists
|
||||||
|
SELECT COUNT(*)
|
||||||
|
INTO v_column_exists
|
||||||
|
FROM dba_tab_columns
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND column_name = 'ARCH_FILE_NAME';
|
||||||
|
|
||||||
|
IF v_column_exists > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('INFO: Renaming column ARCH_FILE_NAME to ARCH_PATH...');
|
||||||
|
EXECUTE IMMEDIATE 'ALTER TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED RENAME COLUMN ARCH_FILE_NAME TO ARCH_PATH';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: Column renamed to ARCH_PATH');
|
||||||
|
ELSE
|
||||||
|
DBMS_OUTPUT.PUT_LINE('INFO: Column ARCH_FILE_NAME does not exist (already renamed or first install)');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Check if PROCESS_NAME already exists
|
||||||
|
SELECT COUNT(*)
|
||||||
|
INTO v_process_name_exists
|
||||||
|
FROM dba_tab_columns
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND column_name = 'PROCESS_NAME';
|
||||||
|
|
||||||
|
IF v_process_name_exists = 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('INFO: Adding new column PROCESS_NAME...');
|
||||||
|
EXECUTE IMMEDIATE 'ALTER TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED ADD (PROCESS_NAME VARCHAR2(200))';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: Column PROCESS_NAME added');
|
||||||
|
|
||||||
|
-- Add comment on new column
|
||||||
|
EXECUTE IMMEDIATE 'COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.PROCESS_NAME IS ''Name of the process that created this record''';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: Comment added to PROCESS_NAME column');
|
||||||
|
ELSE
|
||||||
|
DBMS_OUTPUT.PUT_LINE('INFO: Column PROCESS_NAME already exists');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: A_SOURCE_FILE_RECEIVED table structure updated successfully');
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('ERROR: Failed to update table structure: ' || SQLERRM);
|
||||||
|
RAISE;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT ====================================================================
|
||||||
|
PROMPT A_SOURCE_FILE_RECEIVED Table Update Completed
|
||||||
|
PROMPT ====================================================================
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
-- ====================================================================
|
||||||
|
-- MARS-835-PREHOOK ROLLBACK: Revert A_SOURCE_FILE_RECEIVED Table Structure
|
||||||
|
-- ====================================================================
|
||||||
|
-- Purpose:
|
||||||
|
-- 1. Rename column ARCH_PATH back to ARCH_FILE_NAME
|
||||||
|
-- 2. Remove column PROCESS_NAME
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-13
|
||||||
|
-- ====================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
SET TIMING ON
|
||||||
|
|
||||||
|
PROMPT ====================================================================
|
||||||
|
PROMPT MARS-835-PREHOOK ROLLBACK: Reverting A_SOURCE_FILE_RECEIVED table
|
||||||
|
PROMPT ====================================================================
|
||||||
|
|
||||||
|
DECLARE
|
||||||
|
v_column_exists NUMBER;
|
||||||
|
v_process_name_exists NUMBER;
|
||||||
|
BEGIN
|
||||||
|
-- Check if ARCH_PATH exists (needs to be renamed back)
|
||||||
|
SELECT COUNT(*)
|
||||||
|
INTO v_column_exists
|
||||||
|
FROM dba_tab_columns
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND column_name = 'ARCH_PATH';
|
||||||
|
|
||||||
|
IF v_column_exists > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('INFO: Renaming column ARCH_PATH back to ARCH_FILE_NAME...');
|
||||||
|
EXECUTE IMMEDIATE 'ALTER TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED RENAME COLUMN ARCH_PATH TO ARCH_FILE_NAME';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: Column renamed back to ARCH_FILE_NAME');
|
||||||
|
ELSE
|
||||||
|
DBMS_OUTPUT.PUT_LINE('INFO: Column ARCH_PATH does not exist (already rolled back)');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Check if PROCESS_NAME exists (needs to be dropped)
|
||||||
|
SELECT COUNT(*)
|
||||||
|
INTO v_process_name_exists
|
||||||
|
FROM dba_tab_columns
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND column_name = 'PROCESS_NAME';
|
||||||
|
|
||||||
|
IF v_process_name_exists > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('INFO: Dropping column PROCESS_NAME...');
|
||||||
|
EXECUTE IMMEDIATE 'ALTER TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED DROP COLUMN PROCESS_NAME';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: Column PROCESS_NAME dropped');
|
||||||
|
ELSE
|
||||||
|
DBMS_OUTPUT.PUT_LINE('INFO: Column PROCESS_NAME does not exist (already rolled back)');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: A_SOURCE_FILE_RECEIVED table structure rollback completed');
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('ERROR: Failed to rollback table structure: ' || SQLERRM);
|
||||||
|
RAISE;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT ====================================================================
|
||||||
|
PROMPT A_SOURCE_FILE_RECEIVED Table Rollback Completed
|
||||||
|
PROMPT ====================================================================
|
||||||
@@ -31,6 +31,7 @@ PROMPT =========================================================================
|
|||||||
PROMPT
|
PROMPT
|
||||||
PROMPT This script will:
|
PROMPT This script will:
|
||||||
PROMPT - Create A_PARALLEL_EXPORT_CHUNKS table with unique timestamp task names
|
PROMPT - Create A_PARALLEL_EXPORT_CHUNKS table with unique timestamp task names
|
||||||
|
PROMPT - Update A_SOURCE_FILE_RECEIVED table (rename ARCH_FILE_NAME to ARCH_PATH, add PROCESS_NAME column)
|
||||||
PROMPT - Update ENV_MANAGER to v3.2.0 (add parallel execution error codes)
|
PROMPT - Update ENV_MANAGER to v3.2.0 (add parallel execution error codes)
|
||||||
PROMPT - Update DATA_EXPORTER to v2.4.0 (DBMS_PARALLEL_EXECUTE + Smart Column Mapping)
|
PROMPT - Update DATA_EXPORTER to v2.4.0 (DBMS_PARALLEL_EXECUTE + Smart Column Mapping)
|
||||||
PROMPT - Add pParallelDegree parameter (1-16 threads) to EXPORT_*_BY_DATE procedures
|
PROMPT - Add pParallelDegree parameter (1-16 threads) to EXPORT_*_BY_DATE procedures
|
||||||
@@ -59,25 +60,31 @@ PROMPT =========================================================================
|
|||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 2: Deploy ENV_MANAGER Package
|
PROMPT Step 2: Update A_SOURCE_FILE_RECEIVED Table Structure
|
||||||
|
PROMPT =========================================================================
|
||||||
|
@@03_MARS_835_PREHOOK_update_SOURCE_FILE_RECEIVED_table.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT =========================================================================
|
||||||
|
PROMPT Step 3: Deploy ENV_MANAGER Package
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@01_MARS_835_PREHOOK_install_ENV_MANAGER.sql
|
@@01_MARS_835_PREHOOK_install_ENV_MANAGER.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 3: Deploy DATA_EXPORTER Package
|
PROMPT Step 4: Deploy DATA_EXPORTER Package
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@02_MARS_835_PREHOOK_install_DATA_EXPORTER.sql
|
@@02_MARS_835_PREHOOK_install_DATA_EXPORTER.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 4: Track Package Versions
|
PROMPT Step 5: Track Package Versions
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@track_package_versions.sql
|
@@track_package_versions.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 5: Verify Package Versions
|
PROMPT Step 6: Verify Package Versions
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@verify_packages_version.sql
|
@@verify_packages_version.sql
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ END;
|
|||||||
/
|
/
|
||||||
|
|
||||||
CREATE TABLE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS (
|
CREATE TABLE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS (
|
||||||
CHUNK_ID NUMBER PRIMARY KEY,
|
CHUNK_ID NUMBER NOT NULL,
|
||||||
TASK_NAME VARCHAR2(100) NOT NULL,
|
TASK_NAME VARCHAR2(100) NOT NULL,
|
||||||
YEAR_VALUE VARCHAR2(4) NOT NULL,
|
YEAR_VALUE VARCHAR2(4) NOT NULL,
|
||||||
MONTH_VALUE VARCHAR2(2) NOT NULL,
|
MONTH_VALUE VARCHAR2(2) NOT NULL,
|
||||||
@@ -43,17 +43,20 @@ CREATE TABLE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS (
|
|||||||
FILE_BASE_NAME VARCHAR2(1000),
|
FILE_BASE_NAME VARCHAR2(1000),
|
||||||
TEMPLATE_TABLE_NAME VARCHAR2(200),
|
TEMPLATE_TABLE_NAME VARCHAR2(200),
|
||||||
MAX_FILE_SIZE NUMBER DEFAULT 104857600 NOT NULL,
|
MAX_FILE_SIZE NUMBER DEFAULT 104857600 NOT NULL,
|
||||||
|
JOB_CLASS VARCHAR2(128),
|
||||||
STATUS VARCHAR2(30) DEFAULT 'PENDING' NOT NULL,
|
STATUS VARCHAR2(30) DEFAULT 'PENDING' NOT NULL,
|
||||||
ERROR_MESSAGE VARCHAR2(4000),
|
ERROR_MESSAGE VARCHAR2(4000),
|
||||||
EXPORT_TIMESTAMP TIMESTAMP,
|
EXPORT_TIMESTAMP TIMESTAMP,
|
||||||
CREATED_DATE TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
|
CREATED_DATE TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
||||||
|
CONSTRAINT PK_PARALLEL_EXPORT_CHUNKS PRIMARY KEY (TASK_NAME, CHUNK_ID)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX IX_PARALLEL_CHUNKS_TASK ON CT_MRDS.A_PARALLEL_EXPORT_CHUNKS(TASK_NAME);
|
-- Index for status-based queries (e.g., WHERE STATUS = 'FAILED' AND TASK_NAME = ?)
|
||||||
|
CREATE INDEX IX_PARALLEL_CHUNKS_STATUS_TASK ON CT_MRDS.A_PARALLEL_EXPORT_CHUNKS(STATUS, TASK_NAME);
|
||||||
|
|
||||||
COMMENT ON TABLE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS IS 'Permanent table for parallel export chunk processing (DBMS_PARALLEL_EXECUTE) - permanent because GTT data not visible in parallel callback sessions';
|
COMMENT ON TABLE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS IS 'Permanent table for parallel export chunk processing (DBMS_PARALLEL_EXECUTE) - permanent because GTT data not visible in parallel callback sessions. PK: (TASK_NAME, CHUNK_ID) ensures session isolation for concurrent exports.';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.CHUNK_ID IS 'Unique chunk identifier (partition number)';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.CHUNK_ID IS 'Chunk identifier within task (partition number) - unique per TASK_NAME, not globally';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.TASK_NAME IS 'DBMS_PARALLEL_EXECUTE task name for cleanup';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.TASK_NAME IS 'DBMS_PARALLEL_EXECUTE task name - session isolation key, part of composite PK with CHUNK_ID';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.YEAR_VALUE IS 'Partition year (YYYY)';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.YEAR_VALUE IS 'Partition year (YYYY)';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.MONTH_VALUE IS 'Partition month (MM)';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.MONTH_VALUE IS 'Partition month (MM)';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.SCHEMA_NAME IS 'Schema owning the source table';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.SCHEMA_NAME IS 'Schema owning the source table';
|
||||||
@@ -69,6 +72,7 @@ COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.FORMAT_TYPE IS 'Export format
|
|||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.FILE_BASE_NAME IS 'Base filename for CSV exports (NULL for Parquet)';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.FILE_BASE_NAME IS 'Base filename for CSV exports (NULL for Parquet)';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.TEMPLATE_TABLE_NAME IS 'Template table name for per-column date format configuration (e.g., CT_ET_TEMPLATES.TABLE_NAME)';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.TEMPLATE_TABLE_NAME IS 'Template table name for per-column date format configuration (e.g., CT_ET_TEMPLATES.TABLE_NAME)';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.MAX_FILE_SIZE IS 'Maximum file size in bytes for CSV exports only (e.g., 104857600 = 100MB, 1073741824 = 1GB) - default 100MB (104857600). NOTE: Not applicable for PARQUET format (Oracle limitation)';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.MAX_FILE_SIZE IS 'Maximum file size in bytes for CSV exports only (e.g., 104857600 = 100MB, 1073741824 = 1GB) - default 100MB (104857600). NOTE: Not applicable for PARQUET format (Oracle limitation)';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.JOB_CLASS IS 'Oracle Scheduler job class name for resource management (e.g., ''high'', ''DEFAULT_JOB_CLASS'') - NULL uses default scheduler priority';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.STATUS IS 'Chunk processing status: PENDING (not started), PROCESSING (in progress), COMPLETED (success), FAILED (error) - allows retry of failed partitions only';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.STATUS IS 'Chunk processing status: PENDING (not started), PROCESSING (in progress), COMPLETED (success), FAILED (error) - allows retry of failed partitions only';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.ERROR_MESSAGE IS 'Error message if chunk processing failed (STATUS = FAILED)';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.ERROR_MESSAGE IS 'Error message if chunk processing failed (STATUS = FAILED)';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.EXPORT_TIMESTAMP IS 'Timestamp when chunk export was completed (STATUS = COMPLETED)';
|
COMMENT ON COLUMN CT_MRDS.A_PARALLEL_EXPORT_CHUNKS.EXPORT_TIMESTAMP IS 'Timestamp when chunk export was completed (STATUS = COMPLETED)';
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
-- ====================================================================
|
||||||
|
-- A_SOURCE_FILE_RECEIVED Table
|
||||||
|
-- ====================================================================
|
||||||
|
-- Purpose: Track received files and their processing status
|
||||||
|
-- ====================================================================
|
||||||
|
|
||||||
|
CREATE TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED (
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
A_SOURCE_FILE_CONFIG_KEY NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
SOURCE_FILE_NAME VARCHAR2(1000) NOT NULL,
|
||||||
|
CHECKSUM VARCHAR2(128),
|
||||||
|
CREATED TIMESTAMP(6) WITH TIME ZONE,
|
||||||
|
BYTES NUMBER,
|
||||||
|
RECEPTION_DATE DATE NOT NULL,
|
||||||
|
PROCESSING_STATUS VARCHAR2(200),
|
||||||
|
EXTERNAL_TABLE_NAME VARCHAR2(200),
|
||||||
|
PARTITION_YEAR VARCHAR2(4),
|
||||||
|
PARTITION_MONTH VARCHAR2(2),
|
||||||
|
ARCH_PATH VARCHAR2(1000),
|
||||||
|
PROCESS_NAME VARCHAR2(200),
|
||||||
|
CONSTRAINT A_SOURCE_FILE_RECEIVED_PK PRIMARY KEY (A_SOURCE_FILE_RECEIVED_KEY),
|
||||||
|
CONSTRAINT ASFR_A_SOURCE_FILE_CONFIG_KEY_FK FOREIGN KEY(A_SOURCE_FILE_CONFIG_KEY) REFERENCES CT_MRDS.A_SOURCE_FILE_CONFIG(A_SOURCE_FILE_CONFIG_KEY),
|
||||||
|
CONSTRAINT A_SOURCE_FILE_RECEIVED_CHK CHECK (PROCESSING_STATUS IN ('RECEIVED', 'VALIDATED', 'READY_FOR_INGESTION', 'INGESTED', 'ARCHIVED'))
|
||||||
|
) TABLESPACE "DATA";
|
||||||
|
|
||||||
|
-- Unique index for file identification (workaround for TIMESTAMP WITH TIMEZONE constraint limitation)
|
||||||
|
CREATE UNIQUE INDEX CT_MRDS.A_SOURCE_FILE_RECEIVED_UK1
|
||||||
|
ON CT_MRDS.A_SOURCE_FILE_RECEIVED(CHECKSUM, CREATED, BYTES);
|
||||||
|
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON CT_MRDS.A_SOURCE_FILE_RECEIVED TO MRDS_LOADER_ROLE;
|
||||||
@@ -18,34 +18,104 @@ AS
|
|||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes export file from OCI bucket if it exists (used for cleanup before retry)
|
* Deletes ALL files matching specific file pattern before retry export
|
||||||
* Silently ignores if file doesn't exist (ORA-20404)
|
* Critical for preventing data duplication when DBMS_CLOUD.EXPORT_DATA fails mid-process
|
||||||
|
*
|
||||||
|
* Problem: Export fails after creating partial file(s), retry creates new _2, _3 suffixed files
|
||||||
|
* Solution: Delete ALL files matching the base filename pattern before retry
|
||||||
|
*
|
||||||
|
* Pattern matching strategy:
|
||||||
|
* - Parquet: folder/PARTITION_YEAR=2024/PARTITION_MONTH=11/*.parquet (folder-level safe - each chunk has own partition folder)
|
||||||
|
* - CSV: folder/TABLENAME_202411*.csv (file-level pattern - multiple chunks share same folder!)
|
||||||
|
*
|
||||||
|
* CRITICAL for parallel processing:
|
||||||
|
* - Parquet chunks are isolated by partition folder structure (safe to delete folder/*)
|
||||||
|
* - CSV chunks share flat folder structure - MUST use file-specific pattern (TABLENAME_YYYYMM*)
|
||||||
|
* to avoid deleting files from other parallel chunks in same folder
|
||||||
**/
|
**/
|
||||||
PROCEDURE DELETE_FAILED_EXPORT_FILE(
|
PROCEDURE DELETE_FAILED_EXPORT_FILE(
|
||||||
pFileUri IN VARCHAR2,
|
pFileUri IN VARCHAR2,
|
||||||
pCredentialName IN VARCHAR2,
|
pCredentialName IN VARCHAR2,
|
||||||
pParameters IN VARCHAR2
|
pParameters IN VARCHAR2
|
||||||
) IS
|
) IS
|
||||||
|
vBucketUri VARCHAR2(4000);
|
||||||
|
vFolderPath VARCHAR2(4000);
|
||||||
|
vFileName VARCHAR2(1000);
|
||||||
|
vFileNamePattern VARCHAR2(1000);
|
||||||
|
vSlashPos NUMBER;
|
||||||
|
vDotPos NUMBER;
|
||||||
|
vFilesDeleted NUMBER := 0;
|
||||||
BEGIN
|
BEGIN
|
||||||
BEGIN
|
-- Extract components from URI
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Attempting to delete potentially corrupted file: ' || pFileUri, 'DEBUG', pParameters);
|
-- Example Parquet: https://.../bucket/folder/PARTITION_YEAR=2024/PARTITION_MONTH=11/202411.parquet
|
||||||
|
-- Example CSV: https://.../bucket/folder/TABLENAME_202411.csv
|
||||||
|
|
||||||
|
-- Find last slash before filename
|
||||||
|
vSlashPos := INSTR(pFileUri, '/', -1);
|
||||||
|
|
||||||
|
IF vSlashPos > 0 THEN
|
||||||
|
-- Extract filename from URI (after last slash)
|
||||||
|
vFileName := SUBSTR(pFileUri, vSlashPos + 1);
|
||||||
|
|
||||||
DBMS_CLOUD.DELETE_OBJECT(
|
-- Extract folder path (before last slash)
|
||||||
credential_name => pCredentialName,
|
vFolderPath := SUBSTR(pFileUri, 1, vSlashPos - 1);
|
||||||
object_uri => pFileUri
|
|
||||||
);
|
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Deleted existing file (cleanup before retry): ' || pFileUri, 'INFO', pParameters);
|
-- Find bucket URI (protocol + namespace + bucket name)
|
||||||
EXCEPTION
|
-- Bucket URI ends after /o/ in OCI Object Storage URLs
|
||||||
WHEN OTHERS THEN
|
vBucketUri := SUBSTR(pFileUri, 1, INSTR(pFileUri, '/o/') + 2);
|
||||||
-- Object not found is OK (file doesn't exist)
|
|
||||||
IF SQLCODE = -20404 THEN
|
-- Extract relative folder path (after bucket)
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('File does not exist (OK): ' || pFileUri, 'DEBUG', pParameters);
|
vFolderPath := SUBSTR(vFolderPath, LENGTH(vBucketUri) + 1);
|
||||||
ELSE
|
|
||||||
-- Log but don't fail - export will attempt anyway
|
-- Create file pattern by removing extension
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Warning: Could not delete file (will retry export anyway): ' || SQLERRM, 'WARNING', pParameters);
|
-- Oracle adds suffixes BEFORE extension: file.csv -> file_1_timestamp.csv
|
||||||
END IF;
|
-- Pattern: file* matches file_1_timestamp.csv, file_2_timestamp.csv
|
||||||
END;
|
vDotPos := INSTR(vFileName, '.', -1);
|
||||||
|
IF vDotPos > 0 THEN
|
||||||
|
vFileNamePattern := SUBSTR(vFileName, 1, vDotPos - 1) || '%';
|
||||||
|
ELSE
|
||||||
|
vFileNamePattern := vFileName || '%';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Cleanup before retry - Pattern: ' || vFolderPath || '/' || vFileNamePattern, 'DEBUG', pParameters);
|
||||||
|
|
||||||
|
-- List and delete ALL files matching pattern
|
||||||
|
-- CRITICAL: Uses file-specific pattern for CSV chunk isolation in shared folder
|
||||||
|
FOR rec IN (
|
||||||
|
SELECT object_name
|
||||||
|
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
||||||
|
credential_name => pCredentialName,
|
||||||
|
location_uri => vBucketUri
|
||||||
|
))
|
||||||
|
WHERE object_name LIKE vFolderPath || '/' || vFileNamePattern
|
||||||
|
) LOOP
|
||||||
|
BEGIN
|
||||||
|
DBMS_CLOUD.DELETE_OBJECT(
|
||||||
|
credential_name => pCredentialName,
|
||||||
|
object_uri => vBucketUri || rec.object_name
|
||||||
|
);
|
||||||
|
|
||||||
|
vFilesDeleted := vFilesDeleted + 1;
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Deleted partial file ' || vFilesDeleted || ': ' || rec.object_name, 'DEBUG', pParameters);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
-- Log but continue - don't fail entire cleanup
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Warning: Could not delete ' || rec.object_name || ': ' || SQLERRM, 'WARNING', pParameters);
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
IF vFilesDeleted > 0 THEN
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Cleanup completed: Deleted ' || vFilesDeleted || ' partial file(s) from previous failed export', 'INFO', pParameters);
|
||||||
|
ELSE
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('No existing files to clean up (pattern match: ' || vFileNamePattern || ')', 'DEBUG', pParameters);
|
||||||
|
END IF;
|
||||||
|
ELSE
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Warning: Cannot parse file URI for cleanup: ' || pFileUri, 'WARNING', pParameters);
|
||||||
|
END IF;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
-- Don't fail export if cleanup fails - log and continue
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Warning: Cleanup failed (will retry export anyway): ' || SQLERRM, 'WARNING', pParameters);
|
||||||
END DELETE_FAILED_EXPORT_FILE;
|
END DELETE_FAILED_EXPORT_FILE;
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
@@ -415,6 +485,8 @@ AS
|
|||||||
AND L.LOAD_START >= TO_DATE(' || CHR(39) || TO_CHAR(pMinDate, 'YYYY-MM-DD HH24:MI:SS') || CHR(39) || ', ''YYYY-MM-DD HH24:MI:SS'')
|
AND L.LOAD_START >= TO_DATE(' || CHR(39) || TO_CHAR(pMinDate, 'YYYY-MM-DD HH24:MI:SS') || CHR(39) || ', ''YYYY-MM-DD HH24:MI:SS'')
|
||||||
AND L.LOAD_START < TO_DATE(' || CHR(39) || TO_CHAR(pMaxDate, 'YYYY-MM-DD HH24:MI:SS') || CHR(39) || ', ''YYYY-MM-DD HH24:MI:SS'')';
|
AND L.LOAD_START < TO_DATE(' || CHR(39) || TO_CHAR(pMaxDate, 'YYYY-MM-DD HH24:MI:SS') || CHR(39) || ', ''YYYY-MM-DD HH24:MI:SS'')';
|
||||||
|
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Processing Year/Month: ' || pYear || '/' || pMonth || ' (Format: '||pFormat||')', 'DEBUG', pParameters);
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Export query: ' || vQuery, 'DEBUG', pParameters);
|
||||||
-- Construct the URI based on format
|
-- Construct the URI based on format
|
||||||
IF pFormat = 'PARQUET' THEN
|
IF pFormat = 'PARQUET' THEN
|
||||||
-- Parquet: Use Hive-style partitioning
|
-- Parquet: Use Hive-style partitioning
|
||||||
@@ -425,6 +497,7 @@ AS
|
|||||||
'PARTITION_MONTH=' || sanitizeFilename(pMonth) || '/' ||
|
'PARTITION_MONTH=' || sanitizeFilename(pMonth) || '/' ||
|
||||||
sanitizeFilename(pYear) || sanitizeFilename(pMonth) || '.parquet';
|
sanitizeFilename(pYear) || sanitizeFilename(pMonth) || '.parquet';
|
||||||
|
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Parquet export URI: ' || vUri, 'DEBUG', pParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Parquet export URI: ' || vUri, 'DEBUG', pParameters);
|
||||||
|
|
||||||
-- Delete potentially corrupted file from previous failed attempt
|
-- Delete potentially corrupted file from previous failed attempt
|
||||||
@@ -445,6 +518,7 @@ AS
|
|||||||
sanitizeFilename(vFileName);
|
sanitizeFilename(vFileName);
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('CSV export URI: ' || vUri, 'DEBUG', pParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('CSV export URI: ' || vUri, 'DEBUG', pParameters);
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('CSV maxfilesize: ' || pMaxFileSize || ' bytes (' || ROUND(pMaxFileSize/1048576, 2) || ' MB)', 'DEBUG', pParameters);
|
||||||
|
|
||||||
-- Delete potentially corrupted file from previous failed attempt
|
-- Delete potentially corrupted file from previous failed attempt
|
||||||
-- This prevents Oracle from creating _1 suffixed files on retry
|
-- This prevents Oracle from creating _1 suffixed files on retry
|
||||||
@@ -472,8 +546,7 @@ AS
|
|||||||
RAISE_APPLICATION_ERROR(-20001, 'Unsupported format: ' || pFormat || '. Use PARQUET or CSV.');
|
RAISE_APPLICATION_ERROR(-20001, 'Unsupported format: ' || pFormat || '. Use PARQUET or CSV.');
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Processing Year/Month: ' || pYear || '/' || pMonth || ' (Format: ' || pFormat || ')', 'DEBUG', pParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Export completed successfully for ' || pYear || '/' || pMonth, 'DEBUG', pParameters);
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Export query: ' || vQuery, 'DEBUG', pParameters);
|
|
||||||
END EXPORT_SINGLE_PARTITION;
|
END EXPORT_SINGLE_PARTITION;
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
@@ -485,7 +558,8 @@ AS
|
|||||||
**/
|
**/
|
||||||
PROCEDURE EXPORT_PARTITION_PARALLEL (
|
PROCEDURE EXPORT_PARTITION_PARALLEL (
|
||||||
pStartId IN NUMBER,
|
pStartId IN NUMBER,
|
||||||
pEndId IN NUMBER
|
pEndId IN NUMBER,
|
||||||
|
pTaskName IN VARCHAR2 DEFAULT NULL
|
||||||
) IS
|
) IS
|
||||||
vYear VARCHAR2(4);
|
vYear VARCHAR2(4);
|
||||||
vMonth VARCHAR2(2);
|
vMonth VARCHAR2(2);
|
||||||
@@ -501,9 +575,13 @@ AS
|
|||||||
vFormat VARCHAR2(20);
|
vFormat VARCHAR2(20);
|
||||||
vFileBaseName VARCHAR2(1000);
|
vFileBaseName VARCHAR2(1000);
|
||||||
vMaxFileSize NUMBER;
|
vMaxFileSize NUMBER;
|
||||||
|
vJobClass VARCHAR2(128);
|
||||||
|
vTaskName VARCHAR2(128);
|
||||||
vParameters VARCHAR2(4000);
|
vParameters VARCHAR2(4000);
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Retrieve chunk context from global temporary table
|
-- Retrieve chunk context from A_PARALLEL_EXPORT_CHUNKS table
|
||||||
|
-- CRITICAL: Filter by CHUNK_ID and TASK_NAME for precise session isolation
|
||||||
|
-- pTaskName parameter passed from RUN_TASK ensures deterministic single-row retrieval
|
||||||
SELECT
|
SELECT
|
||||||
YEAR_VALUE,
|
YEAR_VALUE,
|
||||||
MONTH_VALUE,
|
MONTH_VALUE,
|
||||||
@@ -518,7 +596,9 @@ AS
|
|||||||
CREDENTIAL_NAME,
|
CREDENTIAL_NAME,
|
||||||
FORMAT_TYPE,
|
FORMAT_TYPE,
|
||||||
FILE_BASE_NAME,
|
FILE_BASE_NAME,
|
||||||
MAX_FILE_SIZE
|
MAX_FILE_SIZE,
|
||||||
|
JOB_CLASS,
|
||||||
|
TASK_NAME
|
||||||
INTO
|
INTO
|
||||||
vYear,
|
vYear,
|
||||||
vMonth,
|
vMonth,
|
||||||
@@ -533,18 +613,23 @@ AS
|
|||||||
vCredentialName,
|
vCredentialName,
|
||||||
vFormat,
|
vFormat,
|
||||||
vFileBaseName,
|
vFileBaseName,
|
||||||
vMaxFileSize
|
vMaxFileSize,
|
||||||
|
vJobClass,
|
||||||
|
vTaskName
|
||||||
FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS
|
FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS
|
||||||
WHERE CHUNK_ID = pStartId;
|
WHERE CHUNK_ID = pStartId
|
||||||
|
AND TASK_NAME = pTaskName;
|
||||||
|
|
||||||
vParameters := 'Parallel task - Year: ' || vYear || ', Month: ' || vMonth || ', ChunkID: ' || pStartId;
|
vParameters := 'Parallel task - Year: ' || vYear || ', Month: ' || vMonth || ', ChunkID: ' || pStartId || ', TaskName: ' || vTaskName;
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Starting parallel export for partition ' || vYear || '/' || vMonth, 'DEBUG', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Starting parallel export for partition ' || vYear || '/' || vMonth, 'DEBUG', vParameters);
|
||||||
|
|
||||||
-- Mark chunk as PROCESSING
|
-- Mark chunk as PROCESSING
|
||||||
|
-- CRITICAL: Use both CHUNK_ID AND TASK_NAME for session isolation
|
||||||
UPDATE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS
|
UPDATE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS
|
||||||
SET STATUS = 'PROCESSING',
|
SET STATUS = 'PROCESSING',
|
||||||
ERROR_MESSAGE = NULL
|
ERROR_MESSAGE = NULL
|
||||||
WHERE CHUNK_ID = pStartId;
|
WHERE CHUNK_ID = pStartId
|
||||||
|
AND TASK_NAME = vTaskName;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- Call the worker procedure
|
-- Call the worker procedure
|
||||||
@@ -567,26 +652,30 @@ AS
|
|||||||
);
|
);
|
||||||
|
|
||||||
-- Mark chunk as COMPLETED
|
-- Mark chunk as COMPLETED
|
||||||
|
-- CRITICAL: Use both CHUNK_ID AND TASK_NAME for session isolation
|
||||||
UPDATE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS
|
UPDATE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS
|
||||||
SET STATUS = 'COMPLETED',
|
SET STATUS = 'COMPLETED',
|
||||||
EXPORT_TIMESTAMP = SYSTIMESTAMP,
|
EXPORT_TIMESTAMP = SYSTIMESTAMP,
|
||||||
ERROR_MESSAGE = NULL
|
ERROR_MESSAGE = NULL
|
||||||
WHERE CHUNK_ID = pStartId;
|
WHERE CHUNK_ID = pStartId
|
||||||
|
AND TASK_NAME = vTaskName;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Completed parallel export for partition ' || vYear || '/' || vMonth, 'DEBUG', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Completed parallel export for partition ' || vYear || '/' || vMonth, 'DEBUG', vParameters);
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
-- Capture error details in variable (SQLERRM cannot be used directly in SQL)
|
-- Capture error details in variable (SQLERRM cannot be used directly in SQL)
|
||||||
vgMsgTmp := 'Parallel task error for partition ' || vYear || '/' || vMonth || ' (ChunkID: ' || pStartId || '): ' || SQLERRM || cgBL || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
|
vgMsgTmp := 'Parallel task error for partition ' || vYear || '/' || vMonth || ' (ChunkID: ' || pStartId || ', TaskName: ' || vTaskName || '): ' || SQLERRM || cgBL || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters);
|
||||||
|
|
||||||
-- Mark chunk as FAILED with error message
|
-- Mark chunk as FAILED with error message
|
||||||
|
-- CRITICAL: Use both CHUNK_ID AND TASK_NAME for session isolation
|
||||||
-- Use vgMsgTmp variable instead of SQLERRM directly (Oracle limitation in SQL context)
|
-- Use vgMsgTmp variable instead of SQLERRM directly (Oracle limitation in SQL context)
|
||||||
UPDATE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS
|
UPDATE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS
|
||||||
SET STATUS = 'FAILED',
|
SET STATUS = 'FAILED',
|
||||||
ERROR_MESSAGE = SUBSTR(vgMsgTmp, 1, 4000)
|
ERROR_MESSAGE = SUBSTR(vgMsgTmp, 1, 4000)
|
||||||
WHERE CHUNK_ID = pStartId;
|
WHERE CHUNK_ID = pStartId
|
||||||
|
AND TASK_NAME = vTaskName;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
RAISE;
|
RAISE;
|
||||||
@@ -606,6 +695,7 @@ AS
|
|||||||
pTemplateTableName IN VARCHAR2 default NULL,
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
pMaxFileSize IN NUMBER default 104857600,
|
pMaxFileSize IN NUMBER default 104857600,
|
||||||
pRegisterExport IN BOOLEAN default FALSE,
|
pRegisterExport IN BOOLEAN default FALSE,
|
||||||
|
pProcessName IN VARCHAR2 default 'DATA_EXPORTER',
|
||||||
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
)
|
)
|
||||||
IS
|
IS
|
||||||
@@ -638,6 +728,7 @@ AS
|
|||||||
,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||''''
|
,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||''''
|
||||||
,'pMaxFileSize => '''||nvl(TO_CHAR(pMaxFileSize), 'NULL')||''''
|
,'pMaxFileSize => '''||nvl(TO_CHAR(pMaxFileSize), 'NULL')||''''
|
||||||
,'pRegisterExport => '''||CASE WHEN pRegisterExport THEN 'TRUE' ELSE 'FALSE' END||''''
|
,'pRegisterExport => '''||CASE WHEN pRegisterExport THEN 'TRUE' ELSE 'FALSE' END||''''
|
||||||
|
,'pProcessName => '''||nvl(pProcessName, 'NULL')||''''
|
||||||
,'pCredentialName => '''||nvl(pCredentialName, 'NULL')||''''
|
,'pCredentialName => '''||nvl(pCredentialName, 'NULL')||''''
|
||||||
));
|
));
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
@@ -750,10 +841,9 @@ AS
|
|||||||
ENV_MANAGER.LOG_PROCESS_EVENT('File registration enabled with config key: ' || vConfigKey, 'INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('File registration enabled with config key: ' || vConfigKey, 'INFO', vParameters);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Construct single query for entire table (no key value partitioning)
|
-- Construct single query for entire table (no join with A_LOAD_HISTORY - ensures single file output)
|
||||||
vQuery := 'SELECT ' || vProcessedColumnList ||
|
vQuery := 'SELECT ' || vProcessedColumnList ||
|
||||||
' FROM ' || vTableName || ' T, CT_ODS.A_LOAD_HISTORY L' ||
|
' FROM ' || vTableName || ' T';
|
||||||
' WHERE T.' || DBMS_ASSERT.simple_sql_name(vKeyColumnName) || ' = L.A_ETL_LOAD_SET_KEY';
|
|
||||||
|
|
||||||
-- Construct the URI for the file in OCI Object Storage
|
-- Construct the URI for the file in OCI Object Storage
|
||||||
vUri := vBucketUri ||
|
vUri := vBucketUri ||
|
||||||
@@ -784,15 +874,14 @@ AS
|
|||||||
-- Register exported file to A_SOURCE_FILE_RECEIVED if requested
|
-- Register exported file to A_SOURCE_FILE_RECEIVED if requested
|
||||||
IF pRegisterExport THEN
|
IF pRegisterExport THEN
|
||||||
DECLARE
|
DECLARE
|
||||||
vChecksum VARCHAR2(128);
|
|
||||||
vCreated TIMESTAMP WITH TIME ZONE;
|
|
||||||
vBytes NUMBER;
|
|
||||||
vActualFileName VARCHAR2(1000); -- Actual filename with Oracle suffix
|
vActualFileName VARCHAR2(1000); -- Actual filename with Oracle suffix
|
||||||
vSanitizedFileName VARCHAR2(1000);
|
vSanitizedFileName VARCHAR2(1000);
|
||||||
vFileName VARCHAR2(1000);
|
vFileName VARCHAR2(1000);
|
||||||
vRetryCount NUMBER := 0;
|
vRetryCount NUMBER := 0;
|
||||||
vMaxRetries NUMBER := 1; -- One retry after initial attempt
|
vMaxRetries NUMBER := 1; -- One retry after initial attempt
|
||||||
vRetryDelay NUMBER := 2; -- 2 seconds delay
|
vRetryDelay NUMBER := 2; -- 2 seconds delay
|
||||||
|
vFilesFound NUMBER := 0;
|
||||||
|
vTotalBytes NUMBER := 0;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Extract filename from URI (after last '/')
|
-- Extract filename from URI (after last '/')
|
||||||
vFileName := SUBSTR(vUri, INSTR(vUri, '/', -1) + 1);
|
vFileName := SUBSTR(vUri, INSTR(vUri, '/', -1) + 1);
|
||||||
@@ -804,24 +893,70 @@ AS
|
|||||||
-- Example: tablename.csv becomes tablename_1_20260211T102621591769Z.csv
|
-- Example: tablename.csv becomes tablename_1_20260211T102621591769Z.csv
|
||||||
vSanitizedFileName := REGEXP_REPLACE(vSanitizedFileName, '\.csv$', '', 1, 0, 'i');
|
vSanitizedFileName := REGEXP_REPLACE(vSanitizedFileName, '\.csv$', '', 1, 0, 'i');
|
||||||
|
|
||||||
-- Try to get file metadata with retry logic
|
-- Try to get ALL exported files with retry logic
|
||||||
|
-- Oracle DBMS_CLOUD.EXPORT_DATA can create MULTIPLE files due to:
|
||||||
|
-- 1. maxfilesize parameter (splits files larger than limit)
|
||||||
|
-- 2. Automatic parallel processing (especially on large production instances)
|
||||||
|
-- We must register ALL files, not just the first one
|
||||||
<<metadata_retry_loop>>
|
<<metadata_retry_loop>>
|
||||||
LOOP
|
LOOP
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT object_name, checksum, created, bytes
|
-- Register ALL files matching the pattern (cursor loop)
|
||||||
INTO vActualFileName, vChecksum, vCreated, vBytes
|
FOR rec IN (
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
SELECT object_name, checksum, created, bytes
|
||||||
credential_name => pCredentialName,
|
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
||||||
location_uri => vBucketUri
|
credential_name => pCredentialName,
|
||||||
))
|
location_uri => vBucketUri
|
||||||
WHERE object_name LIKE CASE WHEN pFolderName IS NOT NULL THEN pFolderName || '/' ELSE '' END || vSanitizedFileName || '%'
|
))
|
||||||
ORDER BY created DESC, bytes DESC
|
WHERE object_name LIKE CASE WHEN pFolderName IS NOT NULL THEN pFolderName || '/' ELSE '' END || vSanitizedFileName || '%'
|
||||||
FETCH FIRST 1 ROW ONLY;
|
ORDER BY created DESC, bytes DESC
|
||||||
|
) LOOP
|
||||||
|
-- Extract filename only from full path (remove bucket folder prefix)
|
||||||
|
vActualFileName := SUBSTR(rec.object_name, INSTR(rec.object_name, '/', -1) + 1);
|
||||||
|
|
||||||
|
-- Create A_SOURCE_FILE_RECEIVED record for EACH exported file
|
||||||
|
vSourceFileReceivedKey := CT_MRDS.A_SOURCE_FILE_RECEIVED_KEY_SEQ.NEXTVAL;
|
||||||
|
INSERT INTO CT_MRDS.A_SOURCE_FILE_RECEIVED (
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY,
|
||||||
|
A_SOURCE_FILE_CONFIG_KEY,
|
||||||
|
SOURCE_FILE_NAME,
|
||||||
|
CHECKSUM,
|
||||||
|
CREATED,
|
||||||
|
BYTES,
|
||||||
|
RECEPTION_DATE,
|
||||||
|
PROCESSING_STATUS,
|
||||||
|
PARTITION_YEAR,
|
||||||
|
PARTITION_MONTH,
|
||||||
|
ARCH_PATH,
|
||||||
|
PROCESS_NAME
|
||||||
|
) VALUES (
|
||||||
|
vSourceFileReceivedKey,
|
||||||
|
NVL(vConfigKey, -1), -- Use config key if found, otherwise -1
|
||||||
|
vActualFileName, -- Use actual filename with Oracle suffix
|
||||||
|
rec.checksum,
|
||||||
|
rec.created,
|
||||||
|
rec.bytes,
|
||||||
|
SYSDATE,
|
||||||
|
'INGESTED',
|
||||||
|
NULL, -- PARTITION_YEAR not used for single-file exports
|
||||||
|
NULL, -- PARTITION_MONTH not used for single-file exports
|
||||||
|
NULL, -- ARCH_PATH not used for single-file exports
|
||||||
|
pProcessName -- Process name from parameter
|
||||||
|
);
|
||||||
|
|
||||||
|
vFilesFound := vFilesFound + 1;
|
||||||
|
vTotalBytes := vTotalBytes + rec.bytes;
|
||||||
|
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Registered file ' || vFilesFound || ': FileReceivedKey=' || vSourceFileReceivedKey || ', File=' || vActualFileName || ', Size=' || rec.bytes || ' bytes', 'INFO', vParameters);
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
-- Extract filename only from full path (remove bucket folder prefix)
|
-- Check if any files were found
|
||||||
vActualFileName := SUBSTR(vActualFileName, INSTR(vActualFileName, '/', -1) + 1);
|
IF vFilesFound = 0 THEN
|
||||||
|
RAISE NO_DATA_FOUND;
|
||||||
|
END IF;
|
||||||
|
|
||||||
-- Success - exit retry loop
|
-- Success - exit retry loop
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Total registered: ' || vFilesFound || ' file(s), Total size: ' || vTotalBytes || ' bytes (' || ROUND(vTotalBytes/1048576, 2) || ' MB)', 'INFO', vParameters);
|
||||||
EXIT metadata_retry_loop;
|
EXIT metadata_retry_loop;
|
||||||
|
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
@@ -830,7 +965,7 @@ AS
|
|||||||
|
|
||||||
IF vRetryCount <= vMaxRetries THEN
|
IF vRetryCount <= vMaxRetries THEN
|
||||||
-- Log retry attempt
|
-- Log retry attempt
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('File not found in bucket (attempt ' || vRetryCount || '/' || (vMaxRetries + 1) || '), retrying after ' || vRetryDelay || ' seconds: ' || vFileName, 'DEBUG', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('File(s) not found in bucket (attempt ' || vRetryCount || '/' || (vMaxRetries + 1) || '), retrying after ' || vRetryDelay || ' seconds: ' || vFileName, 'DEBUG', vParameters);
|
||||||
|
|
||||||
-- Wait before retry using DBMS_SESSION.SLEEP (alternative to DBMS_LOCK)
|
-- Wait before retry using DBMS_SESSION.SLEEP (alternative to DBMS_LOCK)
|
||||||
DBMS_SESSION.SLEEP(vRetryDelay);
|
DBMS_SESSION.SLEEP(vRetryDelay);
|
||||||
@@ -840,36 +975,6 @@ AS
|
|||||||
END IF;
|
END IF;
|
||||||
END;
|
END;
|
||||||
END LOOP metadata_retry_loop;
|
END LOOP metadata_retry_loop;
|
||||||
|
|
||||||
-- Create A_SOURCE_FILE_RECEIVED record for this export with metadata
|
|
||||||
vSourceFileReceivedKey := CT_MRDS.A_SOURCE_FILE_RECEIVED_KEY_SEQ.NEXTVAL;
|
|
||||||
INSERT INTO CT_MRDS.A_SOURCE_FILE_RECEIVED (
|
|
||||||
A_SOURCE_FILE_RECEIVED_KEY,
|
|
||||||
A_SOURCE_FILE_CONFIG_KEY,
|
|
||||||
SOURCE_FILE_NAME,
|
|
||||||
CHECKSUM,
|
|
||||||
CREATED,
|
|
||||||
BYTES,
|
|
||||||
RECEPTION_DATE,
|
|
||||||
PROCESSING_STATUS,
|
|
||||||
PARTITION_YEAR,
|
|
||||||
PARTITION_MONTH,
|
|
||||||
ARCH_FILE_NAME
|
|
||||||
) VALUES (
|
|
||||||
vSourceFileReceivedKey,
|
|
||||||
NVL(vConfigKey, -1), -- Use config key if found, otherwise -1
|
|
||||||
vActualFileName, -- Use actual filename with Oracle suffix
|
|
||||||
vChecksum,
|
|
||||||
vCreated,
|
|
||||||
vBytes,
|
|
||||||
SYSDATE,
|
|
||||||
'INGESTED',
|
|
||||||
NULL, -- PARTITION_YEAR not used for single-file exports
|
|
||||||
NULL, -- PARTITION_MONTH not used for single-file exports
|
|
||||||
NULL -- ARCH_FILE_NAME not used for single-file exports
|
|
||||||
);
|
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Registered file: FileReceivedKey=' || vSourceFileReceivedKey || ', File=' || vActualFileName || ', Size=' || vBytes || ' bytes', 'INFO', vParameters);
|
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN NO_DATA_FOUND THEN
|
WHEN NO_DATA_FOUND THEN
|
||||||
-- File not found after retries - log warning and continue without metadata
|
-- File not found after retries - log warning and continue without metadata
|
||||||
@@ -888,7 +993,8 @@ AS
|
|||||||
PROCESSING_STATUS,
|
PROCESSING_STATUS,
|
||||||
PARTITION_YEAR,
|
PARTITION_YEAR,
|
||||||
PARTITION_MONTH,
|
PARTITION_MONTH,
|
||||||
ARCH_FILE_NAME
|
ARCH_PATH,
|
||||||
|
PROCESS_NAME
|
||||||
) VALUES (
|
) VALUES (
|
||||||
vSourceFileReceivedKey,
|
vSourceFileReceivedKey,
|
||||||
NVL(vConfigKey, -1), -- Use config key if found, otherwise -1
|
NVL(vConfigKey, -1), -- Use config key if found, otherwise -1
|
||||||
@@ -897,7 +1003,8 @@ AS
|
|||||||
'INGESTED',
|
'INGESTED',
|
||||||
NULL, -- PARTITION_YEAR not used for single-file exports
|
NULL, -- PARTITION_YEAR not used for single-file exports
|
||||||
NULL, -- PARTITION_MONTH not used for single-file exports
|
NULL, -- PARTITION_MONTH not used for single-file exports
|
||||||
NULL -- ARCH_FILE_NAME not used for single-file exports
|
NULL, -- ARCH_PATH not used for single-file exports
|
||||||
|
pProcessName -- Process name from parameter
|
||||||
);
|
);
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Registered file without metadata: FileReceivedKey=' || vSourceFileReceivedKey || ', File=' || vSanitizedFileName, 'INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Registered file without metadata: FileReceivedKey=' || vSourceFileReceivedKey || ', File=' || vSanitizedFileName, 'INFO', vParameters);
|
||||||
@@ -935,6 +1042,7 @@ AS
|
|||||||
pMaxDate IN DATE default SYSDATE,
|
pMaxDate IN DATE default SYSDATE,
|
||||||
pParallelDegree IN NUMBER default 1,
|
pParallelDegree IN NUMBER default 1,
|
||||||
pTemplateTableName IN VARCHAR2 default NULL,
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
|
pJobClass IN VARCHAR2 default NULL,
|
||||||
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
)
|
)
|
||||||
IS
|
IS
|
||||||
@@ -958,6 +1066,7 @@ AS
|
|||||||
,'pMaxDate => '''||nvl(TO_CHAR(pMaxDate, 'YYYY-MM-DD HH24:MI:SS'), 'NULL')||''''
|
,'pMaxDate => '''||nvl(TO_CHAR(pMaxDate, 'YYYY-MM-DD HH24:MI:SS'), 'NULL')||''''
|
||||||
,'pParallelDegree => '''||nvl(TO_CHAR(pParallelDegree), 'NULL')||''''
|
,'pParallelDegree => '''||nvl(TO_CHAR(pParallelDegree), 'NULL')||''''
|
||||||
,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||''''
|
,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||''''
|
||||||
|
,'pJobClass => '''||nvl(pJobClass, 'NULL')||''''
|
||||||
,'pCredentialName => '''||nvl(pCredentialName, 'NULL')||''''
|
,'pCredentialName => '''||nvl(pCredentialName, 'NULL')||''''
|
||||||
));
|
));
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
@@ -1029,73 +1138,69 @@ AS
|
|||||||
vChunkId NUMBER;
|
vChunkId NUMBER;
|
||||||
BEGIN
|
BEGIN
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Using parallel processing with ' || pParallelDegree || ' threads', 'INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Using parallel processing with ' || pParallelDegree || ' threads', 'INFO', vParameters);
|
||||||
|
|
||||||
-- Clean up old completed chunks (>24 hours) to prevent table bloat
|
|
||||||
-- CRITICAL: Do NOT delete chunks from other active sessions (same-day tasks)
|
|
||||||
-- This prevents race conditions when multiple exports run simultaneously
|
|
||||||
DELETE FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS
|
|
||||||
WHERE STATUS = 'COMPLETED'
|
|
||||||
AND CREATED_DATE < SYSTIMESTAMP - INTERVAL '1' DAY;
|
|
||||||
COMMIT;
|
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Cleared old COMPLETED chunks (>24h). Active session chunks preserved.', 'DEBUG', vParameters);
|
|
||||||
-- This prevents re-exporting successfully completed partitions
|
|
||||||
DELETE FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'COMPLETED';
|
|
||||||
COMMIT;
|
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Cleared COMPLETED chunks. FAILED chunks retained for retry.', 'DEBUG', vParameters);
|
|
||||||
|
|
||||||
-- Populate chunks table (insert new chunks, preserve FAILED chunks for retry)
|
-- Populate chunks table (insert new chunks, preserve FAILED chunks for retry)
|
||||||
FOR i IN 1 .. vPartitions.COUNT LOOP
|
FOR i IN 1 .. vPartitions.COUNT LOOP
|
||||||
MERGE INTO CT_MRDS.A_PARALLEL_EXPORT_CHUNKS t
|
MERGE INTO CT_MRDS.A_PARALLEL_EXPORT_CHUNKS t
|
||||||
USING (SELECT i AS chunk_id, vPartitions(i).year AS yr, vPartitions(i).month AS mn FROM DUAL) s
|
USING (SELECT i AS chunk_id, vTaskName AS task_name, vPartitions(i).year AS yr, vPartitions(i).month AS mn FROM DUAL) s
|
||||||
ON (t.CHUNK_ID = s.chunk_id)
|
ON (t.CHUNK_ID = s.chunk_id AND t.TASK_NAME = s.task_name)
|
||||||
WHEN NOT MATCHED THEN
|
WHEN NOT MATCHED THEN
|
||||||
INSERT (CHUNK_ID, TASK_NAME, YEAR_VALUE, MONTH_VALUE, SCHEMA_NAME, TABLE_NAME, KEY_COLUMN_NAME,
|
INSERT (CHUNK_ID, TASK_NAME, YEAR_VALUE, MONTH_VALUE, SCHEMA_NAME, TABLE_NAME, KEY_COLUMN_NAME,
|
||||||
BUCKET_URI, FOLDER_NAME, PROCESSED_COLUMNS, MIN_DATE, MAX_DATE,
|
BUCKET_URI, FOLDER_NAME, PROCESSED_COLUMNS, MIN_DATE, MAX_DATE,
|
||||||
CREDENTIAL_NAME, FORMAT_TYPE, FILE_BASE_NAME, TEMPLATE_TABLE_NAME, MAX_FILE_SIZE, STATUS)
|
CREDENTIAL_NAME, FORMAT_TYPE, FILE_BASE_NAME, TEMPLATE_TABLE_NAME, MAX_FILE_SIZE, JOB_CLASS, STATUS)
|
||||||
VALUES (i, vTaskName, vPartitions(i).year, vPartitions(i).month, vSchemaName, vTableName, vKeyColumnName,
|
VALUES (i, vTaskName, vPartitions(i).year, vPartitions(i).month, vSchemaName, vTableName, vKeyColumnName,
|
||||||
vBucketUri, pFolderName, vProcessedColumnList, pMinDate, pMaxDate,
|
vBucketUri, pFolderName, vProcessedColumnList, pMinDate, pMaxDate,
|
||||||
pCredentialName, 'PARQUET', NULL, pTemplateTableName, 104857600, 'PENDING')
|
pCredentialName, 'PARQUET', NULL, pTemplateTableName, 104857600, pJobClass, 'PENDING')
|
||||||
WHEN MATCHED THEN
|
WHEN MATCHED THEN
|
||||||
UPDATE SET TASK_NAME = vTaskName,
|
-- Match found: chunk exists for SAME task (composite PK: TASK_NAME, CHUNK_ID)
|
||||||
STATUS = CASE WHEN t.STATUS = 'FAILED' THEN 'PENDING' ELSE t.STATUS END,
|
-- This handles retry scenario: reset FAILED chunks to PENDING for re-processing
|
||||||
|
UPDATE SET STATUS = CASE WHEN t.STATUS = 'FAILED' THEN 'PENDING' ELSE t.STATUS END,
|
||||||
ERROR_MESSAGE = CASE WHEN t.STATUS = 'FAILED' THEN NULL ELSE t.ERROR_MESSAGE END;
|
ERROR_MESSAGE = CASE WHEN t.STATUS = 'FAILED' THEN NULL ELSE t.ERROR_MESSAGE END;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- Log chunk statistics
|
-- Log chunk statistics (session-safe: only count chunks for THIS task)
|
||||||
DECLARE
|
DECLARE
|
||||||
vPendingCount NUMBER;
|
vPendingCount NUMBER;
|
||||||
vFailedCount NUMBER;
|
vFailedCount NUMBER;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT COUNT(*) INTO vPendingCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'PENDING';
|
SELECT COUNT(*) INTO vPendingCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'PENDING' AND TASK_NAME = vTaskName;
|
||||||
SELECT COUNT(*) INTO vFailedCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'FAILED';
|
SELECT COUNT(*) INTO vFailedCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'FAILED' AND TASK_NAME = vTaskName;
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Chunk statistics: PENDING=' || vPendingCount || ', FAILED (retry)=' || vFailedCount, 'INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Chunk statistics for task ' || vTaskName || ': PENDING=' || vPendingCount || ', FAILED (retry)=' || vFailedCount, 'INFO', vParameters);
|
||||||
END;
|
END;
|
||||||
|
|
||||||
-- Create parallel task
|
-- Create parallel task
|
||||||
DBMS_PARALLEL_EXECUTE.CREATE_TASK(task_name => vTaskName);
|
DBMS_PARALLEL_EXECUTE.CREATE_TASK(task_name => vTaskName);
|
||||||
|
|
||||||
-- Define chunks by number range (1 to partition count)
|
-- Define chunks using SQL query to ensure TASK_NAME isolation
|
||||||
DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_NUMBER_COL(
|
-- CRITICAL: Filter by TASK_NAME to avoid selecting chunks from other concurrent sessions
|
||||||
|
-- CRITICAL: Use START_ID and END_ID aliases to avoid ORA-00960 ambiguous column naming
|
||||||
|
DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_SQL(
|
||||||
task_name => vTaskName,
|
task_name => vTaskName,
|
||||||
table_owner => 'CT_MRDS',
|
sql_stmt => 'SELECT CHUNK_ID AS START_ID, CHUNK_ID AS END_ID FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE TASK_NAME = ''' || vTaskName || ''' ORDER BY CHUNK_ID',
|
||||||
table_name => 'A_PARALLEL_EXPORT_CHUNKS',
|
by_rowid => FALSE
|
||||||
table_column => 'CHUNK_ID',
|
|
||||||
chunk_size => 1 -- Each partition is one chunk
|
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Execute task in parallel
|
-- Execute task in parallel
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Executing parallel task: ' || vTaskName, 'DEBUG', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Executing parallel task: ' || vTaskName || CASE WHEN pJobClass IS NOT NULL THEN ' with job class: ' || pJobClass ELSE '' END, 'DEBUG', vParameters);
|
||||||
|
|
||||||
DBMS_PARALLEL_EXECUTE.RUN_TASK(
|
IF pJobClass IS NOT NULL THEN
|
||||||
task_name => vTaskName,
|
DBMS_PARALLEL_EXECUTE.RUN_TASK(
|
||||||
sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id); END;',
|
task_name => vTaskName,
|
||||||
language_flag => DBMS_SQL.NATIVE,
|
sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id, ''' || vTaskName || '''); END;',
|
||||||
parallel_level => pParallelDegree
|
language_flag => DBMS_SQL.NATIVE,
|
||||||
);
|
parallel_level => pParallelDegree,
|
||||||
|
job_class => pJobClass
|
||||||
|
);
|
||||||
|
ELSE
|
||||||
|
DBMS_PARALLEL_EXECUTE.RUN_TASK(
|
||||||
|
task_name => vTaskName,
|
||||||
|
sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id, ''' || vTaskName || '''); END;',
|
||||||
|
language_flag => DBMS_SQL.NATIVE,
|
||||||
|
parallel_level => pParallelDegree
|
||||||
|
);
|
||||||
|
END IF;
|
||||||
|
|
||||||
-- Check for errors
|
-- Check for errors
|
||||||
DECLARE
|
DECLARE
|
||||||
@@ -1199,6 +1304,8 @@ AS
|
|||||||
pTemplateTableName IN VARCHAR2 default NULL,
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
pMaxFileSize IN NUMBER default 104857600,
|
pMaxFileSize IN NUMBER default 104857600,
|
||||||
pRegisterExport IN BOOLEAN default FALSE,
|
pRegisterExport IN BOOLEAN default FALSE,
|
||||||
|
pProcessName IN VARCHAR2 default 'DATA_EXPORTER',
|
||||||
|
pJobClass IN VARCHAR2 default NULL,
|
||||||
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
)
|
)
|
||||||
IS
|
IS
|
||||||
@@ -1236,6 +1343,7 @@ AS
|
|||||||
,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||''''
|
,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||''''
|
||||||
,'pMaxFileSize => '''||nvl(TO_CHAR(pMaxFileSize), 'NULL')||''''
|
,'pMaxFileSize => '''||nvl(TO_CHAR(pMaxFileSize), 'NULL')||''''
|
||||||
,'pRegisterExport => '''||CASE WHEN pRegisterExport THEN 'TRUE' ELSE 'FALSE' END||''''
|
,'pRegisterExport => '''||CASE WHEN pRegisterExport THEN 'TRUE' ELSE 'FALSE' END||''''
|
||||||
|
,'pJobClass => '''||nvl(pJobClass, 'NULL')||''''
|
||||||
,'pCredentialName => '''||nvl(pCredentialName, 'NULL')||''''
|
,'pCredentialName => '''||nvl(pCredentialName, 'NULL')||''''
|
||||||
));
|
));
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
@@ -1339,54 +1447,65 @@ AS
|
|||||||
-- Populate chunks table (insert new chunks, preserve FAILED chunks for retry)
|
-- Populate chunks table (insert new chunks, preserve FAILED chunks for retry)
|
||||||
FOR i IN 1 .. vPartitions.COUNT LOOP
|
FOR i IN 1 .. vPartitions.COUNT LOOP
|
||||||
MERGE INTO CT_MRDS.A_PARALLEL_EXPORT_CHUNKS t
|
MERGE INTO CT_MRDS.A_PARALLEL_EXPORT_CHUNKS t
|
||||||
USING (SELECT i AS chunk_id, vPartitions(i).year AS yr, vPartitions(i).month AS mn FROM DUAL) s
|
USING (SELECT i AS chunk_id, vTaskName AS task_name, vPartitions(i).year AS yr, vPartitions(i).month AS mn FROM DUAL) s
|
||||||
ON (t.CHUNK_ID = s.chunk_id)
|
ON (t.CHUNK_ID = s.chunk_id AND t.TASK_NAME = s.task_name)
|
||||||
WHEN NOT MATCHED THEN
|
WHEN NOT MATCHED THEN
|
||||||
INSERT (CHUNK_ID, TASK_NAME, YEAR_VALUE, MONTH_VALUE, SCHEMA_NAME, TABLE_NAME, KEY_COLUMN_NAME,
|
INSERT (CHUNK_ID, TASK_NAME, YEAR_VALUE, MONTH_VALUE, SCHEMA_NAME, TABLE_NAME, KEY_COLUMN_NAME,
|
||||||
BUCKET_URI, FOLDER_NAME, PROCESSED_COLUMNS, MIN_DATE, MAX_DATE,
|
BUCKET_URI, FOLDER_NAME, PROCESSED_COLUMNS, MIN_DATE, MAX_DATE,
|
||||||
CREDENTIAL_NAME, FORMAT_TYPE, FILE_BASE_NAME, TEMPLATE_TABLE_NAME, MAX_FILE_SIZE, STATUS)
|
CREDENTIAL_NAME, FORMAT_TYPE, FILE_BASE_NAME, TEMPLATE_TABLE_NAME, MAX_FILE_SIZE, JOB_CLASS, STATUS)
|
||||||
VALUES (i, vTaskName, vPartitions(i).year, vPartitions(i).month, vSchemaName, vTableName, vKeyColumnName,
|
VALUES (i, vTaskName, vPartitions(i).year, vPartitions(i).month, vSchemaName, vTableName, vKeyColumnName,
|
||||||
vBucketUri, pFolderName, vProcessedColumnList, pMinDate, pMaxDate,
|
vBucketUri, pFolderName, vProcessedColumnList, pMinDate, pMaxDate,
|
||||||
pCredentialName, 'CSV', vFileBaseName, pTemplateTableName, pMaxFileSize, 'PENDING')
|
pCredentialName, 'CSV', vFileBaseName, pTemplateTableName, pMaxFileSize, pJobClass, 'PENDING')
|
||||||
WHEN MATCHED THEN
|
WHEN MATCHED THEN
|
||||||
UPDATE SET TASK_NAME = vTaskName,
|
-- Match found: chunk exists for SAME task (composite PK: TASK_NAME, CHUNK_ID)
|
||||||
STATUS = CASE WHEN t.STATUS = 'FAILED' THEN 'PENDING' ELSE t.STATUS END,
|
-- This handles retry scenario: reset FAILED chunks to PENDING for re-processing
|
||||||
|
UPDATE SET STATUS = CASE WHEN t.STATUS = 'FAILED' THEN 'PENDING' ELSE t.STATUS END,
|
||||||
ERROR_MESSAGE = CASE WHEN t.STATUS = 'FAILED' THEN NULL ELSE t.ERROR_MESSAGE END;
|
ERROR_MESSAGE = CASE WHEN t.STATUS = 'FAILED' THEN NULL ELSE t.ERROR_MESSAGE END;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- Log chunk statistics
|
-- Log chunk statistics (session-safe: only count chunks for THIS task)
|
||||||
DECLARE
|
DECLARE
|
||||||
vPendingCount NUMBER;
|
vPendingCount NUMBER;
|
||||||
vFailedCount NUMBER;
|
vFailedCount NUMBER;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT COUNT(*) INTO vPendingCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'PENDING';
|
SELECT COUNT(*) INTO vPendingCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'PENDING' AND TASK_NAME = vTaskName;
|
||||||
SELECT COUNT(*) INTO vFailedCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'FAILED';
|
SELECT COUNT(*) INTO vFailedCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'FAILED' AND TASK_NAME = vTaskName;
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Chunk statistics: PENDING=' || vPendingCount || ', FAILED (retry)=' || vFailedCount, 'INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Chunk statistics for task ' || vTaskName || ': PENDING=' || vPendingCount || ', FAILED (retry)=' || vFailedCount, 'INFO', vParameters);
|
||||||
END;
|
END;
|
||||||
|
|
||||||
-- Create parallel task
|
-- Create parallel task
|
||||||
DBMS_PARALLEL_EXECUTE.CREATE_TASK(task_name => vTaskName);
|
DBMS_PARALLEL_EXECUTE.CREATE_TASK(task_name => vTaskName);
|
||||||
|
|
||||||
-- Define chunks by number range (1 to partition count)
|
-- Define chunks using SQL query to ensure TASK_NAME isolation
|
||||||
DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_NUMBER_COL(
|
-- CRITICAL: Filter by TASK_NAME to avoid selecting chunks from other concurrent sessions
|
||||||
|
-- CRITICAL: Use START_ID and END_ID aliases to avoid ORA-00960 ambiguous column naming
|
||||||
|
DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_SQL(
|
||||||
task_name => vTaskName,
|
task_name => vTaskName,
|
||||||
table_owner => 'CT_MRDS',
|
sql_stmt => 'SELECT CHUNK_ID AS START_ID, CHUNK_ID AS END_ID FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE TASK_NAME = ''' || vTaskName || ''' ORDER BY CHUNK_ID',
|
||||||
table_name => 'A_PARALLEL_EXPORT_CHUNKS',
|
by_rowid => FALSE
|
||||||
table_column => 'CHUNK_ID',
|
|
||||||
chunk_size => 1 -- Each partition is one chunk
|
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Execute task in parallel
|
-- Execute task in parallel
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Executing parallel CSV export task: ' || vTaskName, 'DEBUG', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Executing parallel CSV export task: ' || vTaskName || CASE WHEN pJobClass IS NOT NULL THEN ' with job class: ' || pJobClass ELSE '' END, 'DEBUG', vParameters);
|
||||||
|
|
||||||
DBMS_PARALLEL_EXECUTE.RUN_TASK(
|
IF pJobClass IS NOT NULL THEN
|
||||||
task_name => vTaskName,
|
DBMS_PARALLEL_EXECUTE.RUN_TASK(
|
||||||
sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id); END;',
|
task_name => vTaskName,
|
||||||
language_flag => DBMS_SQL.NATIVE,
|
sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id, ''' || vTaskName || '''); END;',
|
||||||
parallel_level => pParallelDegree
|
language_flag => DBMS_SQL.NATIVE,
|
||||||
);
|
parallel_level => pParallelDegree,
|
||||||
|
job_class => pJobClass
|
||||||
|
);
|
||||||
|
ELSE
|
||||||
|
DBMS_PARALLEL_EXECUTE.RUN_TASK(
|
||||||
|
task_name => vTaskName,
|
||||||
|
sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id, ''' || vTaskName || '''); END;',
|
||||||
|
language_flag => DBMS_SQL.NATIVE,
|
||||||
|
parallel_level => pParallelDegree
|
||||||
|
);
|
||||||
|
END IF;
|
||||||
|
|
||||||
-- Check for errors
|
-- Check for errors
|
||||||
DECLARE
|
DECLARE
|
||||||
@@ -1545,7 +1664,8 @@ AS
|
|||||||
PROCESSING_STATUS,
|
PROCESSING_STATUS,
|
||||||
PARTITION_YEAR,
|
PARTITION_YEAR,
|
||||||
PARTITION_MONTH,
|
PARTITION_MONTH,
|
||||||
ARCH_FILE_NAME
|
ARCH_PATH,
|
||||||
|
PROCESS_NAME
|
||||||
) VALUES (
|
) VALUES (
|
||||||
vSourceFileReceivedKey,
|
vSourceFileReceivedKey,
|
||||||
vConfigKey, -- Config key from A_SOURCE_FILE_CONFIG lookup
|
vConfigKey, -- Config key from A_SOURCE_FILE_CONFIG lookup
|
||||||
@@ -1557,7 +1677,8 @@ AS
|
|||||||
'INGESTED',
|
'INGESTED',
|
||||||
NULL, -- PARTITION_YEAR not used for CSV exports
|
NULL, -- PARTITION_YEAR not used for CSV exports
|
||||||
NULL, -- PARTITION_MONTH not used for CSV exports
|
NULL, -- PARTITION_MONTH not used for CSV exports
|
||||||
NULL -- ARCH_FILE_NAME not used for CSV exports
|
NULL, -- ARCH_PATH not used for CSV exports
|
||||||
|
pProcessName -- Process name from parameter
|
||||||
);
|
);
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Registered file: FileReceivedKey=' || vSourceFileReceivedKey || ', File=' || vActualFileName || ', Size=' || vBytes || ' bytes', 'DEBUG', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Registered file: FileReceivedKey=' || vSourceFileReceivedKey || ', File=' || vActualFileName || ', Size=' || vBytes || ' bytes', 'DEBUG', vParameters);
|
||||||
@@ -1579,7 +1700,8 @@ AS
|
|||||||
PROCESSING_STATUS,
|
PROCESSING_STATUS,
|
||||||
PARTITION_YEAR,
|
PARTITION_YEAR,
|
||||||
PARTITION_MONTH,
|
PARTITION_MONTH,
|
||||||
ARCH_FILE_NAME
|
ARCH_PATH,
|
||||||
|
PROCESS_NAME
|
||||||
) VALUES (
|
) VALUES (
|
||||||
vSourceFileReceivedKey,
|
vSourceFileReceivedKey,
|
||||||
vConfigKey, -- Config key from A_SOURCE_FILE_CONFIG lookup
|
vConfigKey, -- Config key from A_SOURCE_FILE_CONFIG lookup
|
||||||
@@ -1588,7 +1710,8 @@ AS
|
|||||||
'INGESTED',
|
'INGESTED',
|
||||||
NULL, -- PARTITION_YEAR not used for CSV exports
|
NULL, -- PARTITION_YEAR not used for CSV exports
|
||||||
NULL, -- PARTITION_MONTH not used for CSV exports
|
NULL, -- PARTITION_MONTH not used for CSV exports
|
||||||
NULL -- ARCH_FILE_NAME not used for CSV exports
|
NULL, -- ARCH_PATH not used for CSV exports
|
||||||
|
pProcessName -- Process name from parameter
|
||||||
);
|
);
|
||||||
END;
|
END;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|||||||
@@ -9,18 +9,17 @@ AS
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
-- Package Version Information
|
-- Package Version Information
|
||||||
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '2.8.0';
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '2.14.0';
|
||||||
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-12 09:00:00';
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-25 09:00:00';
|
||||||
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski';
|
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski';
|
||||||
|
|
||||||
-- Version History (last 3-5 changes)
|
-- Version History (last 3-5 changes)
|
||||||
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
||||||
'v2.8.0 (2026-02-12): MAJOR REFACTOR - EXPORT_TABLE_DATA now exports to single CSV file instead of partitioning by key values. Added pFileName parameter.' || CHR(10) ||
|
'v2.14.0 (2026-02-25): OPTIMIZATION - Added pTaskName parameter to EXPORT_PARTITION_PARALLEL for deterministic filtering. Replaced FETCH FIRST 1 ROW ONLY safeguard with precise WHERE CHUNK_ID AND TASK_NAME filter. Eliminates ORDER BY overhead and provides cleaner session isolation.' || CHR(10) ||
|
||||||
'v2.7.5 (2026-02-11): Added pRegisterExport parameter to EXPORT_TABLE_DATA procedure. When TRUE, registers each exported CSV file in A_SOURCE_FILE_RECEIVED.' || CHR(10) ||
|
'v2.13.1 (2026-02-25): CRITICAL FIX - Added START_ID and END_ID aliasses in CREATE_CHUNKS_BY_SQL to avoid ORA-00960 ambiguous column naming error.' || CHR(10) ||
|
||||||
'v2.7.4 (2026-02-11): ACTUAL FILENAME STORAGE - Store real filename with Oracle suffix in SOURCE_FILE_NAME instead of theoretical filename.' || CHR(10) ||
|
'v2.13.0 (2026-02-25): CRITICAL SESSION ISOLATION FIX - Changed CREATE_CHUNKS_BY_NUMBER_COL to CREATE_CHUNKS_BY_SQL with TASK_NAME filter (fixes ORA-01422 in concurrent sessions). Added ORDER BY CREATED_DATE DESC FETCH FIRST 1 ROW safeguard to EXPORT_PARTITION_PARALLEL SELECT. Composite PK (TASK_NAME, CHUNK_ID) now fully functional.' || CHR(10) ||
|
||||||
'v2.7.3 (2026-02-11): FIX LIKE pattern for DBMS_CLOUD.LIST_OBJECTS - Removed .csv extension from filename before pattern matching.' || CHR(10) ||
|
'v2.12.0 (2026-02-24): CRITICAL FIX - Rewritten DELETE_FAILED_EXPORT_FILE to use file-specific pattern matching (prevents deleting parallel CSV chunks in shared folder). Added vQuery logging before DBMS_CLOUD calls. Added CSV maxfilesize logging.' || CHR(10) ||
|
||||||
'v2.7.2 (2026-02-11): FIX pRegisterExport in EXPORT_TABLE_DATA_TO_CSV_BY_DATE - Added missing pRegisterExport parameter to EXPORT_SINGLE_PARTITION call.' || CHR(10) ||
|
'v2.11.0 (2026-02-18): Added pJobClass parameter to EXPORT_TABLE_DATA_BY_DATE and EXPORT_TABLE_DATA_TO_CSV_BY_DATE for Oracle Scheduler job class support (resource/priority management).' || CHR(10);
|
||||||
'v2.7.1 (2026-02-11): AUTO-LOOKUP A_SOURCE_FILE_CONFIG_KEY - Parse pFolderName to automatically find config key from A_SOURCE_FILE_CONFIG.' || CHR(10);
|
|
||||||
|
|
||||||
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
||||||
vgMsgTmp VARCHAR2(32000);
|
vgMsgTmp VARCHAR2(32000);
|
||||||
@@ -55,10 +54,12 @@ AS
|
|||||||
* but should NOT be called directly by external code.
|
* but should NOT be called directly by external code.
|
||||||
* @param pStartId - Chunk start ID (CHUNK_ID from A_PARALLEL_EXPORT_CHUNKS table)
|
* @param pStartId - Chunk start ID (CHUNK_ID from A_PARALLEL_EXPORT_CHUNKS table)
|
||||||
* @param pEndId - Chunk end ID (same as pStartId for single-row chunks)
|
* @param pEndId - Chunk end ID (same as pStartId for single-row chunks)
|
||||||
|
* @param pTaskName - Task name for session isolation (optional, DEFAULT NULL for backward compatibility)
|
||||||
**/
|
**/
|
||||||
PROCEDURE EXPORT_PARTITION_PARALLEL (
|
PROCEDURE EXPORT_PARTITION_PARALLEL (
|
||||||
pStartId IN NUMBER,
|
pStartId IN NUMBER,
|
||||||
pEndId IN NUMBER
|
pEndId IN NUMBER,
|
||||||
|
pTaskName IN VARCHAR2 DEFAULT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -80,6 +81,7 @@ AS
|
|||||||
* - NULL = use source table columns in natural order
|
* - NULL = use source table columns in natural order
|
||||||
* @param pMaxFileSize - Maximum file size in bytes (default 104857600 = 100MB, min 10MB, max 1GB)
|
* @param pMaxFileSize - Maximum file size in bytes (default 104857600 = 100MB, min 10MB, max 1GB)
|
||||||
* @param pRegisterExport - When TRUE, registers exported CSV file in A_SOURCE_FILE_RECEIVED table
|
* @param pRegisterExport - When TRUE, registers exported CSV file in A_SOURCE_FILE_RECEIVED table
|
||||||
|
* @param pProcessName - Process name stored in PROCESS_NAME column (default 'DATA_EXPORTER')
|
||||||
* @example
|
* @example
|
||||||
* begin
|
* begin
|
||||||
* DATA_EXPORTER.EXPORT_TABLE_DATA(
|
* DATA_EXPORTER.EXPORT_TABLE_DATA(
|
||||||
@@ -105,6 +107,7 @@ AS
|
|||||||
pTemplateTableName IN VARCHAR2 default NULL,
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
pMaxFileSize IN NUMBER default 104857600,
|
pMaxFileSize IN NUMBER default 104857600,
|
||||||
pRegisterExport IN BOOLEAN default FALSE,
|
pRegisterExport IN BOOLEAN default FALSE,
|
||||||
|
pProcessName IN VARCHAR2 default 'DATA_EXPORTER',
|
||||||
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -146,6 +149,7 @@ AS
|
|||||||
pMaxDate IN DATE default SYSDATE,
|
pMaxDate IN DATE default SYSDATE,
|
||||||
pParallelDegree IN NUMBER default 1,
|
pParallelDegree IN NUMBER default 1,
|
||||||
pTemplateTableName IN VARCHAR2 default NULL,
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
|
pJobClass IN VARCHAR2 default NULL,
|
||||||
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -161,6 +165,7 @@ AS
|
|||||||
* File naming pattern: {pFileName}_YYYYMM.csv or {TABLENAME}_YYYYMM.csv (if pFileName is NULL)
|
* File naming pattern: {pFileName}_YYYYMM.csv or {TABLENAME}_YYYYMM.csv (if pFileName is NULL)
|
||||||
* When pRegisterExport=TRUE, successfully exported files are registered in:
|
* When pRegisterExport=TRUE, successfully exported files are registered in:
|
||||||
* - CT_MRDS.A_SOURCE_FILE_RECEIVED (tracks file location, size, checksum, and metadata)
|
* - CT_MRDS.A_SOURCE_FILE_RECEIVED (tracks file location, size, checksum, and metadata)
|
||||||
|
* @param pProcessName - Process name stored in PROCESS_NAME column (default 'DATA_EXPORTER')
|
||||||
* @example
|
* @example
|
||||||
* begin
|
* begin
|
||||||
* -- With custom filename
|
* -- With custom filename
|
||||||
@@ -206,6 +211,8 @@ AS
|
|||||||
pTemplateTableName IN VARCHAR2 default NULL,
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
pMaxFileSize IN NUMBER default 104857600,
|
pMaxFileSize IN NUMBER default 104857600,
|
||||||
pRegisterExport IN BOOLEAN default FALSE,
|
pRegisterExport IN BOOLEAN default FALSE,
|
||||||
|
pProcessName IN VARCHAR2 default 'DATA_EXPORTER',
|
||||||
|
pJobClass IN VARCHAR2 default NULL,
|
||||||
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ PROMPT MARS-835-PREHOOK: Rollback to Previous Versions
|
|||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT WARNING: This will reverse all changes from MARS-835-PREHOOK installation!
|
PROMPT WARNING: This will reverse all changes from MARS-835-PREHOOK installation!
|
||||||
PROMPT - Removes A_PARALLEL_EXPORT_CHUNKS table
|
PROMPT - Removes A_PARALLEL_EXPORT_CHUNKS table
|
||||||
|
PROMPT - Reverts A_SOURCE_FILE_RECEIVED table (rename ARCH_PATH to ARCH_FILE_NAME, drop PROCESS_NAME column)
|
||||||
PROMPT - Restores ENV_MANAGER v3.1.0 (removes parallel error codes)
|
PROMPT - Restores ENV_MANAGER v3.1.0 (removes parallel error codes)
|
||||||
PROMPT - Restores DATA_EXPORTER v2.1.0 (removes parallel + Smart Column Mapping)
|
PROMPT - Restores DATA_EXPORTER v2.1.0 (removes parallel + Smart Column Mapping)
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@ -65,13 +66,19 @@ PROMPT =========================================================================
|
|||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 3: Track Rollback Version
|
PROMPT Step 3: Rollback A_SOURCE_FILE_RECEIVED Table Structure
|
||||||
|
PROMPT =========================================================================
|
||||||
|
@@93_MARS_835_PREHOOK_rollback_SOURCE_FILE_RECEIVED_table.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT =========================================================================
|
||||||
|
PROMPT Step 4: Track Rollback Version
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@track_package_versions.sql
|
@@track_package_versions.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 4: Verify Package Versions After Rollback
|
PROMPT Step 5: Verify Package Versions After Rollback
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@verify_packages_version.sql
|
@@verify_packages_version.sql
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
-- ====================================================================
|
||||||
|
-- A_SOURCE_FILE_RECEIVED Table
|
||||||
|
-- ====================================================================
|
||||||
|
-- Purpose: Track received files and their processing status
|
||||||
|
-- ====================================================================
|
||||||
|
|
||||||
|
CREATE TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED (
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
A_SOURCE_FILE_CONFIG_KEY NUMBER(38,0) NOT NULL ENABLE,
|
||||||
|
SOURCE_FILE_NAME VARCHAR2(1000) NOT NULL,
|
||||||
|
CHECKSUM VARCHAR2(128),
|
||||||
|
CREATED TIMESTAMP(6) WITH TIME ZONE,
|
||||||
|
BYTES NUMBER,
|
||||||
|
RECEPTION_DATE DATE NOT NULL,
|
||||||
|
PROCESSING_STATUS VARCHAR2(200),
|
||||||
|
EXTERNAL_TABLE_NAME VARCHAR2(200),
|
||||||
|
PARTITION_YEAR VARCHAR2(4),
|
||||||
|
PARTITION_MONTH VARCHAR2(2),
|
||||||
|
ARCH_FILE_NAME VARCHAR2(1000),
|
||||||
|
CONSTRAINT A_SOURCE_FILE_RECEIVED_PK PRIMARY KEY (A_SOURCE_FILE_RECEIVED_KEY),
|
||||||
|
CONSTRAINT ASFR_A_SOURCE_FILE_CONFIG_KEY_FK FOREIGN KEY(A_SOURCE_FILE_CONFIG_KEY) REFERENCES CT_MRDS.A_SOURCE_FILE_CONFIG(A_SOURCE_FILE_CONFIG_KEY),
|
||||||
|
CONSTRAINT A_SOURCE_FILE_RECEIVED_CHK CHECK (PROCESSING_STATUS IN ('RECEIVED', 'VALIDATED', 'READY_FOR_INGESTION', 'INGESTED', 'ARCHIVED'))
|
||||||
|
) TABLESPACE "DATA";
|
||||||
|
|
||||||
|
-- Unique index for file identification (workaround for TIMESTAMP WITH TIMEZONE constraint limitation)
|
||||||
|
CREATE UNIQUE INDEX CT_MRDS.A_SOURCE_FILE_RECEIVED_UK1
|
||||||
|
ON CT_MRDS.A_SOURCE_FILE_RECEIVED(CHECKSUM, CREATED, BYTES);
|
||||||
|
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON CT_MRDS.A_SOURCE_FILE_RECEIVED TO MRDS_LOADER_ROLE;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,239 @@
|
|||||||
|
create or replace PACKAGE CT_MRDS.DATA_EXPORTER
|
||||||
|
AUTHID CURRENT_USER
|
||||||
|
AS
|
||||||
|
/**
|
||||||
|
* Data Export Package: Provides comprehensive data export capabilities to various formats (CSV, Parquet)
|
||||||
|
* with support for cloud storage integration via Oracle Cloud Infrastructure (OCI).
|
||||||
|
* The structure of comment is used by GET_PACKAGE_DOCUMENTATION function
|
||||||
|
* which returns documentation text for confluence page (to Copy-Paste it).
|
||||||
|
**/
|
||||||
|
|
||||||
|
-- Package Version Information
|
||||||
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '2.9.0';
|
||||||
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-13 14:00:00';
|
||||||
|
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski';
|
||||||
|
|
||||||
|
-- Version History (last 3-5 changes)
|
||||||
|
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
||||||
|
'v2.9.0 (2026-02-13): Added pProcessName parameter to EXPORT_TABLE_DATA and EXPORT_TABLE_DATA_TO_CSV_BY_DATE procedures for process tracking in A_SOURCE_FILE_RECEIVED table.' || CHR(10) ||
|
||||||
|
'v2.8.1 (2026-02-12): FIX query in EXPORT_TABLE_DATA - removed A_LOAD_HISTORY join to ensure single file output (simple SELECT).' || CHR(10) ||
|
||||||
|
'v2.8.0 (2026-02-12): MAJOR REFACTOR - EXPORT_TABLE_DATA now exports to single CSV file instead of partitioning by key values. Added pFileName parameter.' || CHR(10) ||
|
||||||
|
'v2.7.5 (2026-02-11): Added pRegisterExport parameter to EXPORT_TABLE_DATA procedure. When TRUE, registers each exported CSV file in A_SOURCE_FILE_RECEIVED.' || CHR(10) ||
|
||||||
|
'v2.7.4 (2026-02-11): ACTUAL FILENAME STORAGE - Store real filename with Oracle suffix in SOURCE_FILE_NAME instead of theoretical filename.' || CHR(10);
|
||||||
|
|
||||||
|
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
||||||
|
vgMsgTmp VARCHAR2(32000);
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- TYPE DEFINITIONS FOR PARTITION HANDLING
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record type for year/month partition information
|
||||||
|
**/
|
||||||
|
TYPE partition_rec IS RECORD (
|
||||||
|
year VARCHAR2(4),
|
||||||
|
month VARCHAR2(2)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table type for collection of partition records
|
||||||
|
**/
|
||||||
|
TYPE partition_tab IS TABLE OF partition_rec;
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- INTERNAL PARALLEL PROCESSING CALLBACK
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name EXPORT_PARTITION_PARALLEL
|
||||||
|
* @desc Internal callback procedure for DBMS_PARALLEL_EXECUTE.
|
||||||
|
* Processes single partition (year/month) chunk in parallel task.
|
||||||
|
* Called by DBMS_PARALLEL_EXECUTE framework for each chunk.
|
||||||
|
* This procedure is PUBLIC because DBMS_PARALLEL_EXECUTE requires it,
|
||||||
|
* but should NOT be called directly by external code.
|
||||||
|
* @param pStartId - Chunk start ID (CHUNK_ID from A_PARALLEL_EXPORT_CHUNKS table)
|
||||||
|
* @param pEndId - Chunk end ID (same as pStartId for single-row chunks)
|
||||||
|
**/
|
||||||
|
PROCEDURE EXPORT_PARTITION_PARALLEL (
|
||||||
|
pStartId IN NUMBER,
|
||||||
|
pEndId IN NUMBER
|
||||||
|
);
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- MAIN EXPORT PROCEDURES
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name EXPORT_TABLE_DATA
|
||||||
|
* @desc Wrapper procedure for DBMS_CLOUD.EXPORT_DATA.
|
||||||
|
* Exports data into single CSV file on OCI infrastructure.
|
||||||
|
* pBucketArea parameter accepts: 'INBOX', 'ODS', 'DATA', 'ARCHIVE'
|
||||||
|
* Supports template table for column order and per-column date formatting.
|
||||||
|
* When pRegisterExport=TRUE, successfully exported file is registered in:
|
||||||
|
* - CT_MRDS.A_SOURCE_FILE_RECEIVED (tracks file location, size, checksum, and metadata)
|
||||||
|
* @param pFileName - Optional filename (e.g., 'export.csv'). NULL = auto-generate from table name
|
||||||
|
* @param pTemplateTableName - Optional template table (SCHEMA.TABLE or TABLE) for:
|
||||||
|
* - Column order control (template defines CSV structure)
|
||||||
|
* - Per-column date formatting via FILE_MANAGER.GET_DATE_FORMAT
|
||||||
|
* - NULL = use source table columns in natural order
|
||||||
|
* @param pMaxFileSize - Maximum file size in bytes (default 104857600 = 100MB, min 10MB, max 1GB)
|
||||||
|
* @param pRegisterExport - When TRUE, registers exported CSV file in A_SOURCE_FILE_RECEIVED table
|
||||||
|
* @param pProcessName - Process name stored in PROCESS_NAME column (default 'DATA_EXPORTER')
|
||||||
|
* @example
|
||||||
|
* begin
|
||||||
|
* DATA_EXPORTER.EXPORT_TABLE_DATA(
|
||||||
|
* pSchemaName => 'CT_MRDS',
|
||||||
|
* pTableName => 'MY_TABLE',
|
||||||
|
* pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
|
* pBucketArea => 'DATA',
|
||||||
|
* pFolderName => 'csv_exports',
|
||||||
|
* pFileName => 'my_export.csv', -- Optional
|
||||||
|
* pTemplateTableName => 'CT_ET_TEMPLATES.MY_TEMPLATE', -- Optional
|
||||||
|
* pMaxFileSize => 104857600, -- Optional, default 100MB
|
||||||
|
* pRegisterExport => TRUE -- Optional, default FALSE
|
||||||
|
* );
|
||||||
|
* end;
|
||||||
|
**/
|
||||||
|
PROCEDURE EXPORT_TABLE_DATA (
|
||||||
|
pSchemaName IN VARCHAR2,
|
||||||
|
pTableName IN VARCHAR2,
|
||||||
|
pKeyColumnName IN VARCHAR2,
|
||||||
|
pBucketArea IN VARCHAR2,
|
||||||
|
pFolderName IN VARCHAR2,
|
||||||
|
pFileName IN VARCHAR2 default NULL,
|
||||||
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
|
pMaxFileSize IN NUMBER default 104857600,
|
||||||
|
pRegisterExport IN BOOLEAN default FALSE,
|
||||||
|
pProcessName IN VARCHAR2 default 'DATA_EXPORTER',
|
||||||
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name EXPORT_TABLE_DATA_BY_DATE
|
||||||
|
* @desc Wrapper procedure for DBMS_CLOUD.EXPORT_DATA.
|
||||||
|
* Exports data into PARQUET files on OCI infrustructure.
|
||||||
|
* Each YEAR_MONTH pair goes to seperate file (implicit partitioning).
|
||||||
|
* Allows specifying custom column list or uses T.* if pColumnList is NULL.
|
||||||
|
* Validates that all columns in pColumnList exist in the target table.
|
||||||
|
* Automatically adds 'T.' prefix to column names in pColumnList.
|
||||||
|
* Supports parallel partition processing via pParallelDegree parameter (default 1, range 1-16).
|
||||||
|
* pBucketArea parameter accepts: 'INBOX', 'ODS', 'DATA', 'ARCHIVE'
|
||||||
|
* @example
|
||||||
|
* begin
|
||||||
|
* DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
||||||
|
* pSchemaName => 'CT_MRDS',
|
||||||
|
* pTableName => 'MY_TABLE',
|
||||||
|
* pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
|
* pBucketArea => 'DATA',
|
||||||
|
* pFolderName => 'parquet_exports',
|
||||||
|
* pColumnList => 'COLUMN1, COLUMN2, COLUMN3', -- Optional
|
||||||
|
* pMinDate => DATE '2024-01-01',
|
||||||
|
* pMaxDate => SYSDATE,
|
||||||
|
* pParallelDegree => 8 -- Optional, default 1, range 1-16
|
||||||
|
* );
|
||||||
|
* end;
|
||||||
|
**/
|
||||||
|
PROCEDURE EXPORT_TABLE_DATA_BY_DATE (
|
||||||
|
pSchemaName IN VARCHAR2,
|
||||||
|
pTableName IN VARCHAR2,
|
||||||
|
pKeyColumnName IN VARCHAR2,
|
||||||
|
pBucketArea IN VARCHAR2,
|
||||||
|
pFolderName IN VARCHAR2,
|
||||||
|
pColumnList IN VARCHAR2 default NULL,
|
||||||
|
pMinDate IN DATE default DATE '1900-01-01',
|
||||||
|
pMaxDate IN DATE default SYSDATE,
|
||||||
|
pParallelDegree IN NUMBER default 1,
|
||||||
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name EXPORT_TABLE_DATA_TO_CSV_BY_DATE
|
||||||
|
* @desc Exports data to separate CSV files partitioned by year and month.
|
||||||
|
* Creates one CSV file for each year/month combination found in the data.
|
||||||
|
* Uses the same date filtering mechanism with CT_ODS.A_LOAD_HISTORY as EXPORT_TABLE_DATA_BY_DATE,
|
||||||
|
* but exports to CSV format instead of Parquet.
|
||||||
|
* Supports parallel partition processing via pParallelDegree parameter (1-16).
|
||||||
|
* File naming pattern: {pFileName}_YYYYMM.csv or {TABLENAME}_YYYYMM.csv (if pFileName is NULL)
|
||||||
|
* When pRegisterExport=TRUE, successfully exported files are registered in:
|
||||||
|
* - CT_MRDS.A_SOURCE_FILE_RECEIVED (tracks file location, size, checksum, and metadata)
|
||||||
|
* @param pProcessName - Process name stored in PROCESS_NAME column (default 'DATA_EXPORTER')
|
||||||
|
* @example
|
||||||
|
* begin
|
||||||
|
* -- With custom filename
|
||||||
|
* DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
||||||
|
* pSchemaName => 'CT_MRDS',
|
||||||
|
* pTableName => 'MY_TABLE',
|
||||||
|
* pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
|
* pBucketArea => 'DATA',
|
||||||
|
* pFolderName => 'exports',
|
||||||
|
* pFileName => 'my_export.csv',
|
||||||
|
* pMinDate => DATE '2024-01-01',
|
||||||
|
* pMaxDate => SYSDATE,
|
||||||
|
* pParallelDegree => 8, -- Optional, default 1, range 1-16
|
||||||
|
* pRegisterExport => TRUE -- Optional, default FALSE, registers to A_SOURCE_FILE_RECEIVED
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* -- With auto-generated filename (based on table name only)
|
||||||
|
* DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
||||||
|
* pSchemaName => 'OU_TOP',
|
||||||
|
* pTableName => 'AGGREGATED_ALLOTMENT',
|
||||||
|
* pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
|
* pBucketArea => 'ARCHIVE',
|
||||||
|
* pFolderName => 'exports',
|
||||||
|
* pMinDate => DATE '2025-09-01',
|
||||||
|
* pMaxDate => DATE '2025-09-17',
|
||||||
|
* pRegisterExport => TRUE -- Registers each export to A_SOURCE_FILE_RECEIVED table
|
||||||
|
* );
|
||||||
|
* -- This will create files like: AGGREGATED_ALLOTMENT_202509.csv, etc.
|
||||||
|
* pBucketArea parameter accepts: 'INBOX', 'ODS', 'DATA', 'ARCHIVE'
|
||||||
|
* end;
|
||||||
|
**/
|
||||||
|
PROCEDURE EXPORT_TABLE_DATA_TO_CSV_BY_DATE (
|
||||||
|
pSchemaName IN VARCHAR2,
|
||||||
|
pTableName IN VARCHAR2,
|
||||||
|
pKeyColumnName IN VARCHAR2,
|
||||||
|
pBucketArea IN VARCHAR2,
|
||||||
|
pFolderName IN VARCHAR2,
|
||||||
|
pFileName IN VARCHAR2 DEFAULT NULL,
|
||||||
|
pColumnList IN VARCHAR2 default NULL,
|
||||||
|
pMinDate IN DATE default DATE '1900-01-01',
|
||||||
|
pMaxDate IN DATE default SYSDATE,
|
||||||
|
pParallelDegree IN NUMBER default 1,
|
||||||
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
|
pMaxFileSize IN NUMBER default 104857600,
|
||||||
|
pRegisterExport IN BOOLEAN default FALSE,
|
||||||
|
pProcessName IN VARCHAR2 default 'DATA_EXPORTER',
|
||||||
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
|
);
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- VERSION MANAGEMENT FUNCTIONS
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current package version number
|
||||||
|
* return: Version string in format X.Y.Z (e.g., '2.1.0')
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns comprehensive build information including version, date, and author
|
||||||
|
* return: Formatted string with complete build details
|
||||||
|
**/
|
||||||
|
FUNCTION GET_BUILD_INFO RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the version history with recent changes
|
||||||
|
* return: Multi-line string with version history
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2;
|
||||||
|
|
||||||
|
END;
|
||||||
|
|
||||||
|
/
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,625 @@
|
|||||||
|
create or replace PACKAGE CT_MRDS.ENV_MANAGER
|
||||||
|
AUTHID CURRENT_USER
|
||||||
|
AS
|
||||||
|
/**
|
||||||
|
* General comment for package: Please put comments for functions and procedures as shown in below example.
|
||||||
|
* It is a standard.
|
||||||
|
* The structure of comment is used by GET_PACKAGE_DOCUMENTATION function
|
||||||
|
* which returns documentation text for confluence page (to Copy-Paste it).
|
||||||
|
**/
|
||||||
|
|
||||||
|
-- Example comment:
|
||||||
|
/**
|
||||||
|
* @name EX_PROCEDURE_NAME
|
||||||
|
* @desc Procedure description
|
||||||
|
* @example select ENV_MANAGER.EX_PROCEDURE_NAME(pParameter => 129) from dual;
|
||||||
|
* @ex_rslt Example Result
|
||||||
|
**/
|
||||||
|
|
||||||
|
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
||||||
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.2.0';
|
||||||
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-12-20 10:00:00';
|
||||||
|
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski';
|
||||||
|
|
||||||
|
-- Version History (Latest changes first)
|
||||||
|
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
||||||
|
'3.2.0 (2025-12-20): Added error codes for parallel execution support (CODE_INVALID_PARALLEL_DEGREE -20110, CODE_PARALLEL_EXECUTION_FAILED -20111)' || CHR(13)||CHR(10) ||
|
||||||
|
'3.1.0 (2025-10-22): Added package hash tracking and automatic change detection system (SHA256 hashing)' || CHR(13)||CHR(10) ||
|
||||||
|
'3.0.0 (2025-10-22): Added package versioning system with centralized version management functions' || CHR(13)||CHR(10) ||
|
||||||
|
'2.1.0 (2025-10-15): Added ANALYZE_VALIDATION_ERRORS function for comprehensive CSV validation analysis' || CHR(13)||CHR(10) ||
|
||||||
|
'2.0.0 (2025-10-01): Added LOG_PROCESS_ERROR procedure with enhanced error diagnostics and stack traces' || CHR(13)||CHR(10) ||
|
||||||
|
'1.5.0 (2025-09-20): Added console logging support with gvConsoleLoggingEnabled configuration' || CHR(13)||CHR(10) ||
|
||||||
|
'1.0.0 (2025-09-01): Initial release with error management and configuration system';
|
||||||
|
|
||||||
|
TYPE Error_Record IS RECORD (
|
||||||
|
code PLS_INTEGER,
|
||||||
|
message VARCHAR2(4000)
|
||||||
|
);
|
||||||
|
|
||||||
|
TYPE tErrorList IS TABLE OF Error_Record INDEX BY PLS_INTEGER;
|
||||||
|
|
||||||
|
Errors tErrorList;
|
||||||
|
|
||||||
|
|
||||||
|
guid VARCHAR2(32);
|
||||||
|
gvEnv VARCHAR2(200);
|
||||||
|
gvUsername VARCHAR2(128);
|
||||||
|
gvOsuser VARCHAR2(128);
|
||||||
|
gvMachine VARCHAR2(64);
|
||||||
|
gvModule VARCHAR2(64);
|
||||||
|
|
||||||
|
gvNameSpace VARCHAR2(200);
|
||||||
|
gvRegion VARCHAR2(200);
|
||||||
|
gvDataBucketName VARCHAR2(200);
|
||||||
|
gvInboxBucketName VARCHAR2(200);
|
||||||
|
gvArchiveBucketName VARCHAR2(200);
|
||||||
|
gvDataBucketUri VARCHAR2(200);
|
||||||
|
gvInboxBucketUri VARCHAR2(200);
|
||||||
|
gvArchiveBucketUri VARCHAR2(200);
|
||||||
|
gvCredentialName VARCHAR2(200);
|
||||||
|
|
||||||
|
-- Overwritten by variable "LoggingEnabled" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table
|
||||||
|
gvLoggingEnabled VARCHAR2(3) := 'ON'; -- 'ON' or 'OFF'
|
||||||
|
|
||||||
|
-- Overwritten by variable "MinLogLevel" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table
|
||||||
|
-- Possible values: DEBUG ,INFO ,WARNING ,ERROR
|
||||||
|
gvMinLogLevel VARCHAR2(10) := 'DEBUG';
|
||||||
|
|
||||||
|
-- Overwritten by variable "DefaultDateFormat" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table
|
||||||
|
gvDefaultDateFormat VARCHAR2(200) := 'DD/MM/YYYY HH24:MI:SS';
|
||||||
|
|
||||||
|
-- Overwritten by variable "ConsoleLoggingEnabled" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table
|
||||||
|
gvConsoleLoggingEnabled VARCHAR2(3) := 'ON'; -- 'ON' or 'OFF'
|
||||||
|
|
||||||
|
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
||||||
|
|
||||||
|
vgSourceFileConfigKey PLS_INTEGER;
|
||||||
|
|
||||||
|
vgMsgTmp VARCHAR2(32000);
|
||||||
|
--Exceptions
|
||||||
|
ERR_EMPTY_FILEURI_AND_RECKEY EXCEPTION;
|
||||||
|
CODE_EMPTY_FILEURI_AND_RECKEY CONSTANT PLS_INTEGER := -20001;
|
||||||
|
MSG_EMPTY_FILEURI_AND_RECKEY VARCHAR2(4000) := 'Either pFileUri or pSourceFileReceivedKey must be not null';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_EMPTY_FILEURI_AND_RECKEY
|
||||||
|
,CODE_EMPTY_FILEURI_AND_RECKEY);
|
||||||
|
|
||||||
|
|
||||||
|
ERR_NO_CONFIG_MATCH_FOR_FILEURI EXCEPTION;
|
||||||
|
CODE_NO_CONFIG_MATCH_FOR_FILEURI CONSTANT PLS_INTEGER := -20002;
|
||||||
|
MSG_NO_CONFIG_MATCH_FOR_FILEURI VARCHAR2(4000) := 'No match for source file in A_SOURCE_FILE_CONFIG table'
|
||||||
|
||cgBL||' The file provided in parameter: pFileUri does not have '
|
||||||
|
||cgBL||' coresponding configuration in A_SOURCE_FILE_CONFIG table';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_MATCH_FOR_FILEURI
|
||||||
|
,CODE_NO_CONFIG_MATCH_FOR_FILEURI);
|
||||||
|
|
||||||
|
ERR_MULTIPLE_MATCH_FOR_SRCFILE EXCEPTION;
|
||||||
|
CODE_MULTIPLE_MATCH_FOR_SRCFILE CONSTANT PLS_INTEGER := -20003;
|
||||||
|
MSG_MULTIPLE_MATCH_FOR_SRCFILE VARCHAR2(4000) := 'Multiple match for source file in A_SOURCE_FILE_CONFIG table';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_MATCH_FOR_SRCFILE
|
||||||
|
,CODE_MULTIPLE_MATCH_FOR_SRCFILE);
|
||||||
|
|
||||||
|
ERR_MISSING_COLUMN_DATE_FORMAT EXCEPTION;
|
||||||
|
CODE_MISSING_COLUMN_DATE_FORMAT CONSTANT PLS_INTEGER := -20004;
|
||||||
|
MSG_MISSING_COLUMN_DATE_FORMAT VARCHAR2(4000) := 'Missing entry in config table: A_COLUMN_DATE_FORMAT primary key(TEMPLATE_TABLE_NAME, COLUMN_NAME)'
|
||||||
|
||cgBL||' Remember: each column which data_type IN (''DATE'', ''TIMESTAMP'')'
|
||||||
|
||cgBL||' should have DateFormat specified in A_COLUMN_DATE_FORMAT table '
|
||||||
|
||cgBL||' for example: ''YYYY-MM-DD''';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_MISSING_COLUMN_DATE_FORMAT
|
||||||
|
,CODE_MISSING_COLUMN_DATE_FORMAT);
|
||||||
|
|
||||||
|
ERR_MULTIPLE_COLUMN_DATE_FORMAT EXCEPTION;
|
||||||
|
CODE_MULTIPLE_COLUMN_DATE_FORMAT CONSTANT PLS_INTEGER := -20005;
|
||||||
|
MSG_MULTIPLE_COLUMN_DATE_FORMAT VARCHAR2(4000) := 'Multiple records for date format in A_COLUMN_DATE_FORMAT table'
|
||||||
|
||cgBL||' There should be only one format specified for each DAT/TIMESTAMP column';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_COLUMN_DATE_FORMAT
|
||||||
|
,CODE_MULTIPLE_COLUMN_DATE_FORMAT);
|
||||||
|
|
||||||
|
|
||||||
|
ERR_DIDNT_GET_LOAD_OPERATION_ID EXCEPTION;
|
||||||
|
CODE_DIDNT_GET_LOAD_OPERATION_ID CONSTANT PLS_INTEGER := -20006;
|
||||||
|
MSG_DIDNT_GET_LOAD_OPERATION_ID VARCHAR2(4000) := 'Didnt get load operation id from external table validation';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_DIDNT_GET_LOAD_OPERATION_ID
|
||||||
|
,CODE_DIDNT_GET_LOAD_OPERATION_ID);
|
||||||
|
|
||||||
|
ERR_NO_CONFIG_FOR_RECEIVED_FILE EXCEPTION;
|
||||||
|
CODE_NO_CONFIG_FOR_RECEIVED_FILE CONSTANT PLS_INTEGER := -20007;
|
||||||
|
MSG_NO_CONFIG_FOR_RECEIVED_FILE VARCHAR2(4000) := 'No match for received source file in A_SOURCE_FILE_CONFIG '
|
||||||
|
||cgBL||' or missing data in A_SOURCE_FILE_RECEIVED table for provided pSourceFileReceivedKey parameter';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_FOR_RECEIVED_FILE
|
||||||
|
,CODE_NO_CONFIG_FOR_RECEIVED_FILE);
|
||||||
|
|
||||||
|
ERR_MULTI_CONFIG_FOR_RECEIVED_FILE EXCEPTION;
|
||||||
|
CODE_MULTI_CONFIG_FOR_RECEIVED_FILE CONSTANT PLS_INTEGER := -20008;
|
||||||
|
MSG_MULTI_CONFIG_FOR_RECEIVED_FILE VARCHAR2(4000) := 'Multiple matchs for received source file in A_SOURCE_FILE_CONFIG';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_MULTI_CONFIG_FOR_RECEIVED_FILE
|
||||||
|
,CODE_MULTI_CONFIG_FOR_RECEIVED_FILE);
|
||||||
|
|
||||||
|
ERR_FILE_NOT_FOUND_ON_CLOUD EXCEPTION;
|
||||||
|
CODE_FILE_NOT_FOUND_ON_CLOUD CONSTANT PLS_INTEGER := -20009;
|
||||||
|
MSG_FILE_NOT_FOUND_ON_CLOUD VARCHAR2(4000) := 'File not found on the cloud';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_FILE_NOT_FOUND_ON_CLOUD
|
||||||
|
,CODE_FILE_NOT_FOUND_ON_CLOUD);
|
||||||
|
|
||||||
|
ERR_FILE_VALIDATION_FAILED EXCEPTION;
|
||||||
|
CODE_FILE_VALIDATION_FAILED CONSTANT PLS_INTEGER := -20010;
|
||||||
|
MSG_FILE_VALIDATION_FAILED VARCHAR2(4000) := 'File validation failed';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_FILE_VALIDATION_FAILED
|
||||||
|
,CODE_FILE_VALIDATION_FAILED);
|
||||||
|
|
||||||
|
ERR_EXCESS_COLUMNS_DETECTED EXCEPTION;
|
||||||
|
CODE_EXCESS_COLUMNS_DETECTED CONSTANT PLS_INTEGER := -20011;
|
||||||
|
MSG_EXCESS_COLUMNS_DETECTED VARCHAR2(4000) := 'CSV file contains more columns than template allows';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_EXCESS_COLUMNS_DETECTED
|
||||||
|
,CODE_EXCESS_COLUMNS_DETECTED);
|
||||||
|
|
||||||
|
ERR_NO_CONFIG_MATCH EXCEPTION;
|
||||||
|
CODE_NO_CONFIG_MATCH CONSTANT PLS_INTEGER := -20012;
|
||||||
|
MSG_NO_CONFIG_MATCH VARCHAR2(4000) := 'No match for specified parameters in A_SOURCE_FILE_CONFIG table';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_MATCH
|
||||||
|
,CODE_NO_CONFIG_MATCH);
|
||||||
|
|
||||||
|
ERR_UNKNOWN_PREFIX EXCEPTION;
|
||||||
|
CODE_UNKNOWN_PREFIX CONSTANT PLS_INTEGER := -20013;
|
||||||
|
MSG_UNKNOWN_PREFIX VARCHAR2(4000) := 'Unknown prefix';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_UNKNOWN_PREFIX
|
||||||
|
,CODE_UNKNOWN_PREFIX);
|
||||||
|
|
||||||
|
ERR_TABLE_NOT_EXISTS EXCEPTION;
|
||||||
|
CODE_TABLE_NOT_EXISTS CONSTANT PLS_INTEGER := -20014;
|
||||||
|
MSG_TABLE_NOT_EXISTS VARCHAR2(4000) := 'Table does not exist';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_TABLE_NOT_EXISTS
|
||||||
|
,CODE_TABLE_NOT_EXISTS);
|
||||||
|
|
||||||
|
ERR_COLUMN_NOT_EXISTS EXCEPTION;
|
||||||
|
CODE_COLUMN_NOT_EXISTS CONSTANT PLS_INTEGER := -20015;
|
||||||
|
MSG_COLUMN_NOT_EXISTS VARCHAR2(4000) := 'Column does not exist in table';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_COLUMN_NOT_EXISTS
|
||||||
|
,CODE_COLUMN_NOT_EXISTS);
|
||||||
|
|
||||||
|
ERR_UNSUPPORTED_DATA_TYPE EXCEPTION;
|
||||||
|
CODE_UNSUPPORTED_DATA_TYPE CONSTANT PLS_INTEGER := -20016;
|
||||||
|
MSG_UNSUPPORTED_DATA_TYPE VARCHAR2(4000) := 'Unsupported data type';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_UNSUPPORTED_DATA_TYPE
|
||||||
|
,CODE_UNSUPPORTED_DATA_TYPE);
|
||||||
|
|
||||||
|
ERR_MISSING_SOURCE_KEY EXCEPTION;
|
||||||
|
CODE_MISSING_SOURCE_KEY CONSTANT PLS_INTEGER := -20017;
|
||||||
|
MSG_MISSING_SOURCE_KEY VARCHAR2(4000) := 'The Source was not found in parent table A_SOURCE';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_MISSING_SOURCE_KEY
|
||||||
|
,CODE_MISSING_SOURCE_KEY);
|
||||||
|
|
||||||
|
ERR_NULL_SOURCE_FILE_CONFIG_KEY EXCEPTION;
|
||||||
|
CODE_NULL_SOURCE_FILE_CONFIG_KEY CONSTANT PLS_INTEGER := -20018;
|
||||||
|
MSG_NULL_SOURCE_FILE_CONFIG_KEY VARCHAR2(4000) := 'No entry in A_SOURCE_FILE_CONFIG table for specified A_SOURCE_FILE_CONFIG_KEY';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_NULL_SOURCE_FILE_CONFIG_KEY
|
||||||
|
,CODE_NULL_SOURCE_FILE_CONFIG_KEY);
|
||||||
|
|
||||||
|
ERR_DUPLICATED_SOURCE_KEY EXCEPTION;
|
||||||
|
CODE_DUPLICATED_SOURCE_KEY CONSTANT PLS_INTEGER := -20019;
|
||||||
|
MSG_DUPLICATED_SOURCE_KEY VARCHAR2(4000) := 'The Source already exists in the A_SOURCE table';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_DUPLICATED_SOURCE_KEY
|
||||||
|
,CODE_DUPLICATED_SOURCE_KEY);
|
||||||
|
|
||||||
|
ERR_MISSING_CONTAINER_CONFIG EXCEPTION;
|
||||||
|
CODE_MISSING_CONTAINER_CONFIG CONSTANT PLS_INTEGER := -20020;
|
||||||
|
MSG_MISSING_CONTAINER_CONFIG VARCHAR2(4000) := 'No match in A_SOURCE_FILE_CONFIG table where SOURCE_FILE_TYPE=''CONTAINER'' and specified SOURCE_FILE_ID';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_MISSING_CONTAINER_CONFIG
|
||||||
|
,CODE_MISSING_CONTAINER_CONFIG);
|
||||||
|
|
||||||
|
ERR_MULTIPLE_CONTAINER_ENTRIES EXCEPTION;
|
||||||
|
CODE_MULTIPLE_CONTAINER_ENTRIES CONSTANT PLS_INTEGER := -20021;
|
||||||
|
MSG_MULTIPLE_CONTAINER_ENTRIES VARCHAR2(4000) := 'Multiple matches in A_SOURCE_FILE_CONFIG table where SOURCE_FILE_TYPE=''CONTAINER'' and specified SOURCE_FILE_ID';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_CONTAINER_ENTRIES
|
||||||
|
,CODE_MULTIPLE_CONTAINER_ENTRIES);
|
||||||
|
|
||||||
|
ERR_WRONG_DESTINATION_PARAM EXCEPTION;
|
||||||
|
CODE_WRONG_DESTINATION_PARAM CONSTANT PLS_INTEGER := -20022;
|
||||||
|
MSG_WRONG_DESTINATION_PARAM VARCHAR2(4000) := 'Wrong destination parameter provided.';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_WRONG_DESTINATION_PARAM
|
||||||
|
,CODE_WRONG_DESTINATION_PARAM);
|
||||||
|
|
||||||
|
ERR_FILE_NOT_EXISTS_ON_CLOUD EXCEPTION;
|
||||||
|
CODE_FILE_NOT_EXISTS_ON_CLOUD CONSTANT PLS_INTEGER := -20023;
|
||||||
|
MSG_FILE_NOT_EXISTS_ON_CLOUD VARCHAR2(4000) := 'File not exists on cloud.';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_FILE_NOT_EXISTS_ON_CLOUD
|
||||||
|
,CODE_FILE_NOT_EXISTS_ON_CLOUD);
|
||||||
|
|
||||||
|
ERR_FILE_ALREADY_REGISTERED EXCEPTION;
|
||||||
|
CODE_FILE_ALREADY_REGISTERED CONSTANT PLS_INTEGER := -20024;
|
||||||
|
MSG_FILE_ALREADY_REGISTERED VARCHAR2(4000) := 'File already registered in A_SOURCE_FILE_RECEIVED table.';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_FILE_ALREADY_REGISTERED
|
||||||
|
,CODE_FILE_ALREADY_REGISTERED);
|
||||||
|
|
||||||
|
ERR_WRONG_DATE_TIMESTAMP_FORMAT EXCEPTION;
|
||||||
|
CODE_WRONG_DATE_TIMESTAMP_FORMAT CONSTANT PLS_INTEGER := -20025;
|
||||||
|
MSG_WRONG_DATE_TIMESTAMP_FORMAT VARCHAR2(4000) := 'Provided DATE or TIMESTAMP format has errors (possible duplicated codes, ex: ''DD'').';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_WRONG_DATE_TIMESTAMP_FORMAT
|
||||||
|
,CODE_WRONG_DATE_TIMESTAMP_FORMAT);
|
||||||
|
|
||||||
|
ERR_ENVIRONMENT_NOT_SET EXCEPTION;
|
||||||
|
CODE_ENVIRONMENT_NOT_SET CONSTANT PLS_INTEGER := -20026;
|
||||||
|
MSG_ENVIRONMENT_NOT_SET VARCHAR2(4000) := 'EnvironmentID not set'
|
||||||
|
||cgBL||' Information about environment is needed to get proper configuration values.'
|
||||||
|
||cgBL||' It can be set up in two different ways:'
|
||||||
|
||cgBL||' 1. Set it on session level: execute DBMS_SESSION.SET_IDENTIFIER (client_id => ''dev'')'
|
||||||
|
||cgBL||' 2. Set it on configuration level: Insert into CT_MRDS.A_FILE_MANAGER_CONFIG (ENVIRONMENT_ID,CONFIG_VARIABLE,CONFIG_VARIABLE_VALUE) values (''default'',''environment_id'',''dev'')'
|
||||||
|
||cgBL||' Session level setup (1.) takes precedence over configuration level one (2.)'
|
||||||
|
;
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_ENVIRONMENT_NOT_SET
|
||||||
|
,CODE_ENVIRONMENT_NOT_SET);
|
||||||
|
|
||||||
|
|
||||||
|
ERR_CONFIG_VARIABLE_NOT_SET EXCEPTION;
|
||||||
|
CODE_CONFIG_VARIABLE_NOT_SET CONSTANT PLS_INTEGER := -20027;
|
||||||
|
MSG_CONFIG_VARIABLE_NOT_SET VARCHAR2(4000) := 'Missing configuration value in A_FILE_MANAGER_CONFIG';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_CONFIG_VARIABLE_NOT_SET
|
||||||
|
,CODE_CONFIG_VARIABLE_NOT_SET);
|
||||||
|
|
||||||
|
ERR_NOT_INPUT_SOURCE_FILE_TYPE EXCEPTION;
|
||||||
|
CODE_NOT_INPUT_SOURCE_FILE_TYPE CONSTANT PLS_INTEGER := -20028;
|
||||||
|
MSG_NOT_INPUT_SOURCE_FILE_TYPE VARCHAR2(4000) := 'Archival can be executed only for A_SOURCE_FILE_CONFIG_KEY where SOURCE_FILE_TYPE=''INPUT''';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_NOT_INPUT_SOURCE_FILE_TYPE
|
||||||
|
,CODE_NOT_INPUT_SOURCE_FILE_TYPE);
|
||||||
|
|
||||||
|
ERR_EXP_DATA_FOR_ARCH_FAILED EXCEPTION;
|
||||||
|
CODE_EXP_DATA_FOR_ARCH_FAILED CONSTANT PLS_INTEGER := -20029;
|
||||||
|
MSG_EXP_DATA_FOR_ARCH_FAILED VARCHAR2(4000) := 'Export data for archival failed.';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_EXP_DATA_FOR_ARCH_FAILED
|
||||||
|
,CODE_EXP_DATA_FOR_ARCH_FAILED);
|
||||||
|
|
||||||
|
ERR_RESTORE_FILE_FROM_TRASH EXCEPTION;
|
||||||
|
CODE_RESTORE_FILE_FROM_TRASH CONSTANT PLS_INTEGER := -20030;
|
||||||
|
MSG_RESTORE_FILE_FROM_TRASH VARCHAR2(4000) := 'Unexpected issues occured while archival process. Restoration of exported files failed.';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_RESTORE_FILE_FROM_TRASH
|
||||||
|
,CODE_RESTORE_FILE_FROM_TRASH);
|
||||||
|
|
||||||
|
ERR_CHANGE_STAT_TO_ARCHIVED_FAILED EXCEPTION;
|
||||||
|
CODE_CHANGE_STAT_TO_ARCHIVED_FAILED CONSTANT PLS_INTEGER := -20031;
|
||||||
|
MSG_CHANGE_STAT_TO_ARCHIVED_FAILED VARCHAR2(4000) := 'Failed to change file status to: ARCHIVED in A_SOURCE_FILE_RECEIVED table.';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_CHANGE_STAT_TO_ARCHIVED_FAILED
|
||||||
|
,CODE_CHANGE_STAT_TO_ARCHIVED_FAILED);
|
||||||
|
|
||||||
|
ERR_MOVE_FILE_TO_TRASH_FAILED EXCEPTION;
|
||||||
|
CODE_MOVE_FILE_TO_TRASH_FAILED CONSTANT PLS_INTEGER := -20032;
|
||||||
|
MSG_MOVE_FILE_TO_TRASH_FAILED VARCHAR2(4000) := 'FAILED to move file to TRASH before DROPPING it.';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_MOVE_FILE_TO_TRASH_FAILED
|
||||||
|
,CODE_MOVE_FILE_TO_TRASH_FAILED);
|
||||||
|
|
||||||
|
ERR_DROP_EXPORTED_FILES_FAILED EXCEPTION;
|
||||||
|
CODE_DROP_EXPORTED_FILES_FAILED CONSTANT PLS_INTEGER := -20033;
|
||||||
|
MSG_DROP_EXPORTED_FILES_FAILED VARCHAR2(4000) := 'FAILED to move file to TRASH before DROPPING it.';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_DROP_EXPORTED_FILES_FAILED
|
||||||
|
,CODE_DROP_EXPORTED_FILES_FAILED);
|
||||||
|
|
||||||
|
ERR_INVALID_BUCKET_AREA EXCEPTION;
|
||||||
|
CODE_INVALID_BUCKET_AREA CONSTANT PLS_INTEGER := -20034;
|
||||||
|
MSG_INVALID_BUCKET_AREA VARCHAR2(4000) := 'Invalid bucket area specified. Valid values: INBOX, ODS, DATA, ARCHIVE';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_INVALID_BUCKET_AREA
|
||||||
|
,CODE_INVALID_BUCKET_AREA);
|
||||||
|
|
||||||
|
ERR_INVALID_PARALLEL_DEGREE EXCEPTION;
|
||||||
|
CODE_INVALID_PARALLEL_DEGREE CONSTANT PLS_INTEGER := -20110;
|
||||||
|
MSG_INVALID_PARALLEL_DEGREE VARCHAR2(4000) := 'Invalid parallel degree parameter. Must be between 1 and 16';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_INVALID_PARALLEL_DEGREE
|
||||||
|
,CODE_INVALID_PARALLEL_DEGREE);
|
||||||
|
|
||||||
|
ERR_PARALLEL_EXECUTION_FAILED EXCEPTION;
|
||||||
|
CODE_PARALLEL_EXECUTION_FAILED CONSTANT PLS_INTEGER := -20111;
|
||||||
|
MSG_PARALLEL_EXECUTION_FAILED VARCHAR2(4000) := 'Parallel execution failed';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_PARALLEL_EXECUTION_FAILED
|
||||||
|
,CODE_PARALLEL_EXECUTION_FAILED);
|
||||||
|
|
||||||
|
ERR_UNKNOWN EXCEPTION;
|
||||||
|
CODE_UNKNOWN CONSTANT PLS_INTEGER := -20999;
|
||||||
|
MSG_UNKNOWN VARCHAR2(4000) := 'Unknown Error Occured';
|
||||||
|
PRAGMA EXCEPTION_INIT( ERR_UNKNOWN
|
||||||
|
,CODE_UNKNOWN);
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name LOG_PROCESS_EVENT
|
||||||
|
* @desc Insert a new log record into A_PROCESS_LOG table.
|
||||||
|
* Also outputs to console if gvConsoleLoggingEnabled = 'ON'.
|
||||||
|
* Respects logging level configuration (gvMinLogLevel).
|
||||||
|
* @example ENV_MANAGER.LOG_PROCESS_EVENT('Process completed successfully', 'INFO', 'pParam1=value1');
|
||||||
|
* @ex_rslt Record inserted into A_PROCESS_LOG table and optionally displayed in console output
|
||||||
|
**/
|
||||||
|
PROCEDURE LOG_PROCESS_EVENT (
|
||||||
|
pLogMessage VARCHAR2
|
||||||
|
,pLogLevel VARCHAR2 DEFAULT 'ERROR'
|
||||||
|
,pParameters VARCHAR2 DEFAULT NULL
|
||||||
|
,pProcessName VARCHAR2 DEFAULT 'FILE_MANAGER'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name LOG_PROCESS_ERROR
|
||||||
|
* @desc Insert a detailed error record into A_PROCESS_LOG table with full stack trace, backtrace, and call stack.
|
||||||
|
* This procedure captures comprehensive error information for debugging purposes while
|
||||||
|
* allowing clean user-facing error messages to be raised separately.
|
||||||
|
* @param pLogMessage - Base error message description
|
||||||
|
* @param pParameters - Procedure parameters for context
|
||||||
|
* @param pProcessName - Name of the calling process/package
|
||||||
|
* @ex_rslt Record inserted into A_PROCESS_LOG table with complete error stack information
|
||||||
|
*/
|
||||||
|
PROCEDURE LOG_PROCESS_ERROR (
|
||||||
|
pLogMessage VARCHAR2
|
||||||
|
,pParameters VARCHAR2 DEFAULT NULL
|
||||||
|
,pProcessName VARCHAR2 DEFAULT 'FILE_MANAGER'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name INIT_ERRORS
|
||||||
|
* @desc Loads data into Errors array.
|
||||||
|
* Errors array is a list of Record(Error_Code, Error_Message) index by Error_Code.
|
||||||
|
* Called automatically during package initialization.
|
||||||
|
* @example Called automatically when package is first referenced
|
||||||
|
* @ex_rslt Errors array populated with all error codes and messages
|
||||||
|
**/
|
||||||
|
PROCEDURE INIT_ERRORS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_DEFAULT_ENV
|
||||||
|
* @desc It returns string with name of default environment.
|
||||||
|
* Return string is A_FILE_MANAGER_CONFIG.ENVIRONMENT_ID value.
|
||||||
|
* @example select ENV_MANAGER.GET_DEFAULT_ENV() from dual;
|
||||||
|
* @ex_rslt dev
|
||||||
|
**/
|
||||||
|
FUNCTION GET_DEFAULT_ENV
|
||||||
|
RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name INIT_VARIABLES
|
||||||
|
* @desc For specified pEnv parameter (A_FILE_MANAGER_CONFIG.ENVIRONMENT_ID)
|
||||||
|
* Assign values to following global package variables:
|
||||||
|
* - gvNameSpace
|
||||||
|
* - gvRegion
|
||||||
|
* - gvCredentialName
|
||||||
|
* - gvInboxBucketName
|
||||||
|
* - gvDataBucketName
|
||||||
|
* - gvArchiveBucketName
|
||||||
|
* - gvInboxBucketUri
|
||||||
|
* - gvDataBucketUri
|
||||||
|
* - gvArchiveBucketUri
|
||||||
|
* - gvLoggingEnabled
|
||||||
|
* - gvMinLogLevel
|
||||||
|
* - gvDefaultDateFormat
|
||||||
|
* - gvConsoleLoggingEnabled
|
||||||
|
**/
|
||||||
|
PROCEDURE INIT_VARIABLES(
|
||||||
|
pEnv VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_ERROR_MESSAGE
|
||||||
|
* @desc It returns string with error message for specified pCode (Error_Code).
|
||||||
|
* Error message is take from Errors Array loaded by INIT_ERRORS procedure
|
||||||
|
* @example select ENV_MANAGER.GET_ERROR_MESSAGE(pCode => -20009) from dual;
|
||||||
|
* @ex_rslt File not found on the cloud
|
||||||
|
**/
|
||||||
|
FUNCTION GET_ERROR_MESSAGE(
|
||||||
|
pCode PLS_INTEGER
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_ERROR_STACK
|
||||||
|
* @desc It returns string with all possible error stack info.
|
||||||
|
* Error message is take from Errors Array loaded by INIT_ERRORS procedure
|
||||||
|
* @example
|
||||||
|
* select ENV_MANAGER.GET_ERROR_STACK(
|
||||||
|
* pFormat => 'OUTPUT'
|
||||||
|
* ,pCode => -20009
|
||||||
|
* ,pSourceFileReceivedKey => NULL)
|
||||||
|
* from dual
|
||||||
|
* @ex_rslt
|
||||||
|
* ------------------------------------------------------+
|
||||||
|
* Error Message:
|
||||||
|
* ORA-0000: normal, successful completion
|
||||||
|
* -------------------------------------------------------
|
||||||
|
* Error Stack:
|
||||||
|
* -------------------------------------------------------
|
||||||
|
* Error Backtrace:
|
||||||
|
* ------------------------------------------------------+
|
||||||
|
**/
|
||||||
|
FUNCTION GET_ERROR_STACK(
|
||||||
|
pFormat VARCHAR2
|
||||||
|
,pCode PLS_INTEGER
|
||||||
|
,pSourceFileReceivedKey CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name FORMAT_PARAMETERS
|
||||||
|
* @desc Formats parameter list for logging purposes.
|
||||||
|
* Converts SYS.ODCIVARCHAR2LIST to formatted string with proper NULL handling.
|
||||||
|
* @example select ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('param1=value1', 'param2=NULL')) from dual;
|
||||||
|
* @ex_rslt param1=value1 ,
|
||||||
|
* param2=NULL
|
||||||
|
**/
|
||||||
|
FUNCTION FORMAT_PARAMETERS(
|
||||||
|
pParameterList SYS.ODCIVARCHAR2LIST
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name ANALYZE_VALIDATION_ERRORS
|
||||||
|
* @desc Analyzes CSV validation errors and generates detailed diagnostic report.
|
||||||
|
* Compares CSV structure with template table and provides specific error analysis.
|
||||||
|
* Includes suggested solutions for common validation issues.
|
||||||
|
* @param pValidationLogTable - Name of validation log table (e.g., VALIDATE$242_LOG)
|
||||||
|
* @param pTemplateSchema - Schema of template table (e.g., CT_ET_TEMPLATES)
|
||||||
|
* @param pTemplateTable - Name of template table (e.g., MOCK_PROC_TABLE)
|
||||||
|
* @param pCsvFileUri - URI of CSV file being validated
|
||||||
|
* @example SELECT ENV_MANAGER.ANALYZE_VALIDATION_ERRORS('VALIDATE$242_LOG', 'CT_ET_TEMPLATES', 'MOCK_PROC_TABLE', 'https://...') FROM DUAL;
|
||||||
|
* @ex_rslt Detailed validation analysis report with column mismatches and solutions
|
||||||
|
**/
|
||||||
|
FUNCTION ANALYZE_VALIDATION_ERRORS(
|
||||||
|
pValidationLogTable VARCHAR2,
|
||||||
|
pTemplateSchema VARCHAR2,
|
||||||
|
pTemplateTable VARCHAR2,
|
||||||
|
pCsvFileUri VARCHAR2
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- PACKAGE VERSION MANAGEMENT FUNCTIONS
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_VERSION
|
||||||
|
* @desc Returns the current version number of the ENV_MANAGER package.
|
||||||
|
* Uses semantic versioning format (MAJOR.MINOR.PATCH).
|
||||||
|
* @example SELECT ENV_MANAGER.GET_VERSION() FROM DUAL;
|
||||||
|
* @ex_rslt 3.0.0
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_BUILD_INFO
|
||||||
|
* @desc Returns comprehensive build information including version, build date, and author.
|
||||||
|
* Formatted for display in logs or monitoring systems.
|
||||||
|
* @example SELECT ENV_MANAGER.GET_BUILD_INFO() FROM DUAL;
|
||||||
|
* @ex_rslt Package: ENV_MANAGER
|
||||||
|
* Version: 3.0.0
|
||||||
|
* Build Date: 2025-10-22 16:00:00
|
||||||
|
* Author: Grzegorz Michalski
|
||||||
|
**/
|
||||||
|
FUNCTION GET_BUILD_INFO RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_VERSION_HISTORY
|
||||||
|
* @desc Returns complete version history with all releases and changes.
|
||||||
|
* Shows evolution of package features over time.
|
||||||
|
* @example SELECT ENV_MANAGER.GET_VERSION_HISTORY() FROM DUAL;
|
||||||
|
* @ex_rslt ENV_MANAGER Version History:
|
||||||
|
* 3.0.0 (2025-10-22): Added package versioning system...
|
||||||
|
* 2.1.0 (2025-10-15): Added ANALYZE_VALIDATION_ERRORS function...
|
||||||
|
**/
|
||||||
|
FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_PACKAGE_VERSION_INFO
|
||||||
|
* @desc Universal function to get formatted version information for any package.
|
||||||
|
* This centralized function is used by all packages in the system.
|
||||||
|
* @param pPackageName - Name of the package
|
||||||
|
* @param pVersion - Version string (MAJOR.MINOR.PATCH format)
|
||||||
|
* @param pBuildDate - Build date timestamp
|
||||||
|
* @param pAuthor - Package author name
|
||||||
|
* @example SELECT ENV_MANAGER.GET_PACKAGE_VERSION_INFO('FILE_MANAGER', '2.1.0', '2025-10-22 15:00:00', 'Grzegorz Michalski') FROM DUAL;
|
||||||
|
* @ex_rslt Package: FILE_MANAGER
|
||||||
|
* Version: 2.1.0
|
||||||
|
* Build Date: 2025-10-22 15:00:00
|
||||||
|
* Author: Grzegorz Michalski
|
||||||
|
**/
|
||||||
|
FUNCTION GET_PACKAGE_VERSION_INFO(
|
||||||
|
pPackageName VARCHAR2,
|
||||||
|
pVersion VARCHAR2,
|
||||||
|
pBuildDate VARCHAR2,
|
||||||
|
pAuthor VARCHAR2
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name FORMAT_VERSION_HISTORY
|
||||||
|
* @desc Universal function to format version history for any package.
|
||||||
|
* Adds package name header and proper formatting.
|
||||||
|
* @param pPackageName - Name of the package
|
||||||
|
* @param pVersionHistory - Complete version history text
|
||||||
|
* @example SELECT ENV_MANAGER.FORMAT_VERSION_HISTORY('FILE_MANAGER', '2.1.0 (2025-10-22): Export procedures...') FROM DUAL;
|
||||||
|
* @ex_rslt FILE_MANAGER Version History:
|
||||||
|
* 2.1.0 (2025-10-22): Export procedures...
|
||||||
|
**/
|
||||||
|
FUNCTION FORMAT_VERSION_HISTORY(
|
||||||
|
pPackageName VARCHAR2,
|
||||||
|
pVersionHistory VARCHAR2
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- PACKAGE HASH + CHANGE DETECTION FUNCTIONS
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CALCULATE_PACKAGE_HASH
|
||||||
|
* @desc Calculates SHA256 hash of package source code from ALL_SOURCE.
|
||||||
|
* Returns hash for both SPEC and BODY (if exists).
|
||||||
|
* Used for automatic change detection.
|
||||||
|
* @param pPackageOwner - Schema owner of the package
|
||||||
|
* @param pPackageName - Name of the package
|
||||||
|
* @param pPackageType - Type of package code ('PACKAGE' for SPEC, 'PACKAGE BODY' for BODY)
|
||||||
|
* @example SELECT ENV_MANAGER.CALCULATE_PACKAGE_HASH('CT_MRDS', 'FILE_MANAGER', 'PACKAGE') FROM DUAL;
|
||||||
|
* @ex_rslt A7B3C5D9E8F1234567890ABCDEF... (64-character SHA256 hash)
|
||||||
|
**/
|
||||||
|
FUNCTION CALCULATE_PACKAGE_HASH(
|
||||||
|
pPackageOwner VARCHAR2,
|
||||||
|
pPackageName VARCHAR2,
|
||||||
|
pPackageType VARCHAR2 -- 'PACKAGE' or 'PACKAGE BODY'
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name TRACK_PACKAGE_VERSION
|
||||||
|
* @desc Records package version and source code hash in A_PACKAGE_VERSION_TRACKING table.
|
||||||
|
* Automatically detects if source code changed without version update.
|
||||||
|
* Should be called after every package deployment.
|
||||||
|
* @param pPackageOwner - Schema owner of the package
|
||||||
|
* @param pPackageName - Name of the package
|
||||||
|
* @param pPackageVersion - Current version from PACKAGE_VERSION constant
|
||||||
|
* @param pPackageBuildDate - Build date from PACKAGE_BUILD_DATE constant
|
||||||
|
* @param pPackageAuthor - Author from PACKAGE_AUTHOR constant
|
||||||
|
* @example EXEC ENV_MANAGER.TRACK_PACKAGE_VERSION('CT_MRDS', 'FILE_MANAGER', '3.2.0', '2025-10-22 16:30:00', 'Grzegorz Michalski');
|
||||||
|
* @ex_rslt Record inserted into A_PACKAGE_VERSION_TRACKING with change detection status
|
||||||
|
**/
|
||||||
|
PROCEDURE TRACK_PACKAGE_VERSION(
|
||||||
|
pPackageOwner VARCHAR2,
|
||||||
|
pPackageName VARCHAR2,
|
||||||
|
pPackageVersion VARCHAR2,
|
||||||
|
pPackageBuildDate VARCHAR2,
|
||||||
|
pPackageAuthor VARCHAR2
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CHECK_PACKAGE_CHANGES
|
||||||
|
* @desc Checks if package source code has changed since last tracking.
|
||||||
|
* Compares current hash with last recorded hash in A_PACKAGE_VERSION_TRACKING.
|
||||||
|
* Returns detailed change detection report.
|
||||||
|
* @param pPackageOwner - Schema owner of the package
|
||||||
|
* @param pPackageName - Name of the package
|
||||||
|
* @example SELECT ENV_MANAGER.CHECK_PACKAGE_CHANGES('CT_MRDS', 'FILE_MANAGER') FROM DUAL;
|
||||||
|
* @ex_rslt WARNING: Package changed without version update!
|
||||||
|
* Last Version: 3.2.0
|
||||||
|
* Current Hash (SPEC): A7B3C5D9...
|
||||||
|
* Last Hash (SPEC): B8C4D6E0...
|
||||||
|
* RECOMMENDATION: Update PACKAGE_VERSION and PACKAGE_BUILD_DATE
|
||||||
|
**/
|
||||||
|
FUNCTION CHECK_PACKAGE_CHANGES(
|
||||||
|
pPackageOwner VARCHAR2,
|
||||||
|
pPackageName VARCHAR2
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name GET_PACKAGE_HASH_INFO
|
||||||
|
* @desc Returns formatted information about package hash and tracking history.
|
||||||
|
* Includes current hash, last tracked hash, and change detection status.
|
||||||
|
* @param pPackageOwner - Schema owner of the package
|
||||||
|
* @param pPackageName - Name of the package
|
||||||
|
* @example SELECT ENV_MANAGER.GET_PACKAGE_HASH_INFO('CT_MRDS', 'FILE_MANAGER') FROM DUAL;
|
||||||
|
* @ex_rslt Package: CT_MRDS.FILE_MANAGER
|
||||||
|
* Current Version: 3.2.0
|
||||||
|
* Current Hash (SPEC): A7B3C5D9...
|
||||||
|
* Last Tracked: 2025-10-22 16:30:00
|
||||||
|
* Status: OK - No changes detected
|
||||||
|
**/
|
||||||
|
FUNCTION GET_PACKAGE_HASH_INFO(
|
||||||
|
pPackageOwner VARCHAR2,
|
||||||
|
pPackageName VARCHAR2
|
||||||
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
|
END ENV_MANAGER;
|
||||||
|
/
|
||||||
@@ -1,123 +1,31 @@
|
|||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- MARS-835: Export Group 1 - Split DATA + HIST (DEBT, DEBT_DAILY)
|
-- MARS-835: Export Group 1 - HIST Only (DEBT, DEBT_DAILY)
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- Purpose: Export last 6 months to DATA bucket (CSV), older data to HIST bucket (Parquet)
|
-- Purpose: Export ALL data to HIST bucket (Parquet with Hive-style partitioning)
|
||||||
-- Applies column mapping: A_ETL_LOAD_SET_FK to A_WORKFLOW_HISTORY_KEY
|
-- Applies column mapping: A_ETL_LOAD_SET_FK to A_WORKFLOW_HISTORY_KEY
|
||||||
-- Excludes legacy columns not required in new structure
|
-- Excludes legacy columns not required in new structure
|
||||||
-- USES: DATA_EXPORTER v2.4.0 with pTemplateTableName for column order and date formats
|
-- USES: DATA_EXPORTER v2.12.0 with pTemplateTableName for column order and date formats
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-12-17
|
-- Date: 2025-12-17
|
||||||
-- Updated: 2026-01-11 (Updated to DATA_EXPORTER v2.4.0 with pTemplateTableName)
|
-- Updated: 2026-02-24 (Changed to HIST-only export, no DATA bucket split)
|
||||||
-- Related: MARS-835 - CSDB Data Export
|
-- Related: MARS-835 - CSDB Data Export
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON SIZE UNLIMITED
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
SET TIMING ON
|
SET TIMING ON
|
||||||
|
|
||||||
DEFINE cutoff_date = "TRUNC(ADD_MONTHS(SYSDATE, -6), 'MM')"
|
|
||||||
|
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT Exporting CSDB.DEBT - Split DATA + HIST
|
PROMPT Exporting CSDB.DEBT - HIST Only
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT Last 6 months to DATA bucket (CSV format)
|
PROMPT ALL data to HIST bucket (Parquet with Hive-style partitioning)
|
||||||
PROMPT Older data to HIST bucket (Parquet with partitioning)
|
|
||||||
PROMPT Column mapping: A_ETL_LOAD_SET_FK to A_WORKFLOW_HISTORY_KEY
|
PROMPT Column mapping: A_ETL_LOAD_SET_FK to A_WORKFLOW_HISTORY_KEY
|
||||||
PROMPT Excluded columns: IDIRDEPOSITORY, VA_BONDDURATION
|
PROMPT Excluded columns: IDIRDEPOSITORY, VA_BONDDURATION
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
|
|
||||||
-- PRE-EXPORT CHECK: List existing files and count records
|
-- Export ALL data to HIST bucket (Parquet)
|
||||||
DECLARE
|
-- NEW v2.12.0: Per-column date format handling with template table, full data range
|
||||||
vFileCount NUMBER := 0;
|
|
||||||
vRecordCount NUMBER := 0;
|
|
||||||
vLocationUri VARCHAR2(1000);
|
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get bucket URI for DATA bucket
|
DBMS_OUTPUT.PUT_LINE('Exporting LEGACY_DEBT data to HIST bucket (ALL data)...');
|
||||||
vLocationUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'ODS/CSDB/CSDB_DEBT/';
|
|
||||||
|
|
||||||
-- Count existing files
|
|
||||||
SELECT COUNT(*)
|
|
||||||
INTO vFileCount
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => 'OCI$RESOURCE_PRINCIPAL',
|
|
||||||
location_uri => vLocationUri
|
|
||||||
))
|
|
||||||
WHERE object_name NOT LIKE '%/'; -- Exclude directories
|
|
||||||
|
|
||||||
IF vFileCount > 0 THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('===============================================================================');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('PRE-EXPORT CHECK: Files already exist in DATA bucket');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('===============================================================================');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Location: ' || vLocationUri);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Files found: ' || vFileCount);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
|
|
||||||
-- List existing files
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Existing files:');
|
|
||||||
FOR rec IN (
|
|
||||||
SELECT object_name, bytes, TO_CHAR(last_modified, 'YYYY-MM-DD HH24:MI:SS') AS modified
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => 'OCI$RESOURCE_PRINCIPAL',
|
|
||||||
location_uri => vLocationUri
|
|
||||||
))
|
|
||||||
WHERE object_name NOT LIKE '%/'
|
|
||||||
ORDER BY object_name
|
|
||||||
) LOOP
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' - ' || rec.object_name || ' (' || rec.bytes || ' bytes, ' || rec.modified || ')');
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
-- Count records in external table
|
|
||||||
BEGIN
|
|
||||||
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ODS.CSDB_DEBT_ODS' INTO vRecordCount;
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('>>>');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('>>> Records currently readable via external table: ' || vRecordCount);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('>>>');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------');
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('WARNING: Cannot count records in external table');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
|
|
||||||
END;
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('===============================================================================');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
ELSE
|
|
||||||
DBMS_OUTPUT.PUT_LINE('PRE-EXPORT CHECK: No existing files found in DATA bucket - bucket is clean');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Export recent data to DATA bucket (CSV)
|
|
||||||
-- NEW v2.4.0: Per-column date format handling with template table for column order
|
|
||||||
BEGIN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Exporting LEGACY_DEBT data to DATA bucket (last 6 months)...');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Using Template Table: CT_ET_TEMPLATES.CSDB_DEBT');
|
|
||||||
|
|
||||||
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
|
||||||
pSchemaName => 'OU_CSDB',
|
|
||||||
pTableName => 'LEGACY_DEBT',
|
|
||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
|
||||||
pBucketArea => 'DATA',
|
|
||||||
pFolderName => 'ODS/CSDB/CSDB_DEBT',
|
|
||||||
pMinDate => &cutoff_date,
|
|
||||||
pMaxDate => SYSDATE,
|
|
||||||
pParallelDegree => 16,
|
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_DEBT',
|
|
||||||
pMaxFileSize => 104857600, -- 100MB in bytes (safe for parallel execution, avoids ORA-04036)
|
|
||||||
pRegisterExport => TRUE -- Register exported files in A_SOURCE_FILE_RECEIVED with metadata (CHECKSUM, CREATED, BYTES)
|
|
||||||
);
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_DEBT exported to DATA bucket with template column order');
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Export historical data to HIST bucket (Parquet)
|
|
||||||
-- NEW v2.4.0: Per-column date format handling with template table
|
|
||||||
BEGIN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Exporting LEGACY_DEBT data to HIST bucket (older than 6 months)...');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Using Template Table: CT_ET_TEMPLATES.CSDB_DEBT');
|
DBMS_OUTPUT.PUT_LINE('Using Template Table: CT_ET_TEMPLATES.CSDB_DEBT');
|
||||||
|
|
||||||
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
||||||
@@ -126,9 +34,11 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/CSDB/CSDB_DEBT',
|
pFolderName => 'ARCHIVE/CSDB/CSDB_DEBT',
|
||||||
pMaxDate => &cutoff_date,
|
pMinDate => DATE '1900-01-01', -- Include all historical data
|
||||||
|
pMaxDate => DATE '9999-12-31', -- Include all future dates
|
||||||
pParallelDegree => 16,
|
pParallelDegree => 16,
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_DEBT'
|
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_DEBT',
|
||||||
|
pJobClass => 'high' -- Oracle Scheduler job class for resource management
|
||||||
);
|
);
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_DEBT exported to HIST bucket with template column order');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_DEBT exported to HIST bucket with template column order');
|
||||||
@@ -136,108 +46,18 @@ END;
|
|||||||
/
|
/
|
||||||
|
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT Exporting CSDB.LEGACY_DEBT_DAILY - Split DATA + HIST
|
PROMPT Exporting CSDB.LEGACY_DEBT_DAILY - HIST Only
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT Last 6 months to DATA bucket (CSV format)
|
PROMPT ALL data to HIST bucket (Parquet with Hive-style partitioning)
|
||||||
PROMPT Older data to HIST bucket (Parquet with partitioning)
|
|
||||||
PROMPT Column mapping: A_ETL_LOAD_SET_FK to A_WORKFLOW_HISTORY_KEY
|
PROMPT Column mapping: A_ETL_LOAD_SET_FK to A_WORKFLOW_HISTORY_KEY
|
||||||
PROMPT Excluded columns: STEPID, PROGRAMNAME, PROGRAMCEILING, PROGRAMSTATUS,
|
PROMPT Excluded columns: STEPID, PROGRAMNAME, PROGRAMCEILING, PROGRAMSTATUS,
|
||||||
PROMPT ISSUERNACE21SECTOR, INSTRUMENTQUOTATIONBASIS
|
PROMPT ISSUERNACE21SECTOR, INSTRUMENTQUOTATIONBASIS
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
|
|
||||||
-- PRE-EXPORT CHECK: List existing files and count records
|
-- Export ALL data to HIST bucket (Parquet)
|
||||||
DECLARE
|
-- NEW v2.12.0: Per-column date format handling with template table, full data range
|
||||||
vFileCount NUMBER := 0;
|
|
||||||
vRecordCount NUMBER := 0;
|
|
||||||
vLocationUri VARCHAR2(1000);
|
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get bucket URI for DATA bucket
|
DBMS_OUTPUT.PUT_LINE('Exporting LEGACY_DEBT_DAILY data to HIST bucket (ALL data)...');
|
||||||
vLocationUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA') || 'ODS/CSDB/CSDB_DEBT_DAILY/';
|
|
||||||
|
|
||||||
-- Count existing files
|
|
||||||
SELECT COUNT(*)
|
|
||||||
INTO vFileCount
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => 'OCI$RESOURCE_PRINCIPAL',
|
|
||||||
location_uri => vLocationUri
|
|
||||||
))
|
|
||||||
WHERE object_name NOT LIKE '%/'; -- Exclude directories
|
|
||||||
|
|
||||||
IF vFileCount > 0 THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('===============================================================================');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('PRE-EXPORT CHECK: Files already exist in DATA bucket');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('===============================================================================');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Location: ' || vLocationUri);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Files found: ' || vFileCount);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
|
|
||||||
-- List existing files
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Existing files:');
|
|
||||||
FOR rec IN (
|
|
||||||
SELECT object_name, bytes, TO_CHAR(last_modified, 'YYYY-MM-DD HH24:MI:SS') AS modified
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => 'OCI$RESOURCE_PRINCIPAL',
|
|
||||||
location_uri => vLocationUri
|
|
||||||
))
|
|
||||||
WHERE object_name NOT LIKE '%/'
|
|
||||||
ORDER BY object_name
|
|
||||||
) LOOP
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' - ' || rec.object_name || ' (' || rec.bytes || ' bytes, ' || rec.modified || ')');
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
-- Count records in external table
|
|
||||||
BEGIN
|
|
||||||
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ODS.CSDB_DEBT_DAILY_ODS' INTO vRecordCount;
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('>>>');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('>>> Records currently readable via external table: ' || vRecordCount);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('>>>');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------');
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('WARNING: Cannot count records in external table');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
|
|
||||||
END;
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('===============================================================================');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
ELSE
|
|
||||||
DBMS_OUTPUT.PUT_LINE('PRE-EXPORT CHECK: No existing files found in DATA bucket - bucket is clean');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Export recent data to DATA bucket (CSV)
|
|
||||||
-- NEW v2.4.0: Per-column date format handling with template table for column order
|
|
||||||
BEGIN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Exporting LEGACY_DEBT_DAILY data to DATA bucket (last 6 months)...');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Using Template Table: CT_ET_TEMPLATES.CSDB_DEBT_DAILY');
|
|
||||||
|
|
||||||
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
|
||||||
pSchemaName => 'OU_CSDB',
|
|
||||||
pTableName => 'LEGACY_DEBT_DAILY',
|
|
||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
|
||||||
pBucketArea => 'DATA',
|
|
||||||
pFolderName => 'ODS/CSDB/CSDB_DEBT_DAILY',
|
|
||||||
pMinDate => &cutoff_date,
|
|
||||||
pMaxDate => SYSDATE,
|
|
||||||
pParallelDegree => 16,
|
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_DEBT_DAILY',
|
|
||||||
pMaxFileSize => 104857600, -- 100MB in bytes (safe for parallel execution, avoids ORA-04036)
|
|
||||||
pRegisterExport => TRUE -- Register exported files in A_SOURCE_FILE_RECEIVED with metadata (CHECKSUM, CREATED, BYTES)
|
|
||||||
);
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_DEBT_DAILY exported to DATA bucket with template column order');
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Export historical data to HIST bucket (Parquet)
|
|
||||||
-- NEW v2.4.0: Per-column date format handling with template table
|
|
||||||
BEGIN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Exporting LEGACY_DEBT_DAILY data to HIST bucket (older than 6 months)...');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Using Template Table: CT_ET_TEMPLATES.CSDB_DEBT_DAILY');
|
DBMS_OUTPUT.PUT_LINE('Using Template Table: CT_ET_TEMPLATES.CSDB_DEBT_DAILY');
|
||||||
|
|
||||||
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
||||||
@@ -246,9 +66,11 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/CSDB/CSDB_DEBT_DAILY',
|
pFolderName => 'ARCHIVE/CSDB/CSDB_DEBT_DAILY',
|
||||||
pMaxDate => &cutoff_date,
|
pMinDate => DATE '1900-01-01', -- Include all historical data
|
||||||
|
pMaxDate => DATE '9999-12-31', -- Include all future dates
|
||||||
pParallelDegree => 16,
|
pParallelDegree => 16,
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_DEBT_DAILY'
|
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_DEBT_DAILY',
|
||||||
|
pJobClass => 'high' -- Oracle Scheduler job class for resource management
|
||||||
);
|
);
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_DEBT_DAILY exported to HIST bucket with template column order');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_DEBT_DAILY exported to HIST bucket with template column order');
|
||||||
@@ -258,8 +80,8 @@ END;
|
|||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT Group 1 Export Completed
|
PROMPT Group 1 Export Completed
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT - LEGACY_DEBT: DATA + HIST exported
|
PROMPT - LEGACY_DEBT: HIST exported (ALL data)
|
||||||
PROMPT - LEGACY_DEBT_DAILY: DATA + HIST exported
|
PROMPT - LEGACY_DEBT_DAILY: HIST exported (ALL data)
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
|
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
|
|||||||
@@ -33,9 +33,11 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/CSDB/CSDB_INSTR_RAT_FULL',
|
pFolderName => 'ARCHIVE/CSDB/CSDB_INSTR_RAT_FULL',
|
||||||
pMaxDate => SYSDATE,
|
pMinDate => DATE '1900-01-01', -- Explicit start date for clarity
|
||||||
|
pMaxDate => DATE '9999-12-31', -- Include future dates (MAX_LOAD_START can be beyond SYSDATE)
|
||||||
pParallelDegree => 8,
|
pParallelDegree => 8,
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_INSTR_RAT_FULL'
|
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_INSTR_RAT_FULL',
|
||||||
|
pJobClass => 'high' -- Oracle Scheduler job class for resource management
|
||||||
);
|
);
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_INSTR_RAT_FULL exported to HIST bucket with template column order');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_INSTR_RAT_FULL exported to HIST bucket with template column order');
|
||||||
@@ -60,9 +62,11 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/CSDB/CSDB_INSTR_DESC_FULL',
|
pFolderName => 'ARCHIVE/CSDB/CSDB_INSTR_DESC_FULL',
|
||||||
pMaxDate => SYSDATE,
|
pMinDate => DATE '1900-01-01', -- Explicit start date for clarity
|
||||||
|
pMaxDate => DATE '9999-12-31', -- Include future dates (MAX_LOAD_START can be beyond SYSDATE)
|
||||||
pParallelDegree => 8,
|
pParallelDegree => 8,
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_INSTR_DESC_FULL'
|
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_INSTR_DESC_FULL',
|
||||||
|
pJobClass => 'high' -- Oracle Scheduler job class for resource management
|
||||||
);
|
);
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_INSTR_DESC_FULL exported to HIST bucket with template column order');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_INSTR_DESC_FULL exported to HIST bucket with template column order');
|
||||||
@@ -87,9 +91,11 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/CSDB/CSDB_ISSUER_RAT_FULL',
|
pFolderName => 'ARCHIVE/CSDB/CSDB_ISSUER_RAT_FULL',
|
||||||
pMaxDate => SYSDATE,
|
pMinDate => DATE '1900-01-01', -- Explicit start date for clarity
|
||||||
|
pMaxDate => DATE '9999-12-31', -- Include future dates (MAX_LOAD_START can be beyond SYSDATE)
|
||||||
pParallelDegree => 8,
|
pParallelDegree => 8,
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_ISSUER_RAT_FULL'
|
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_ISSUER_RAT_FULL',
|
||||||
|
pJobClass => 'high' -- Oracle Scheduler job class for resource management
|
||||||
);
|
);
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ISSUER_RAT_FULL exported to HIST bucket with template column order');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ISSUER_RAT_FULL exported to HIST bucket with template column order');
|
||||||
@@ -114,9 +120,11 @@ BEGIN
|
|||||||
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
||||||
pBucketArea => 'ARCHIVE',
|
pBucketArea => 'ARCHIVE',
|
||||||
pFolderName => 'ARCHIVE/CSDB/CSDB_ISSUER_DESC_FULL',
|
pFolderName => 'ARCHIVE/CSDB/CSDB_ISSUER_DESC_FULL',
|
||||||
pMaxDate => SYSDATE,
|
pMinDate => DATE '1900-01-01', -- Explicit start date for clarity
|
||||||
|
pMaxDate => DATE '9999-12-31', -- Include future dates (MAX_LOAD_START can be beyond SYSDATE)
|
||||||
pParallelDegree => 8,
|
pParallelDegree => 8,
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_ISSUER_DESC_FULL'
|
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_ISSUER_DESC_FULL',
|
||||||
|
pJobClass => 'high' -- Oracle Scheduler job class for resource management
|
||||||
);
|
);
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ISSUER_DESC_FULL exported to HIST bucket with template column order');
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: LEGACY_ISSUER_DESC_FULL exported to HIST bucket with template column order');
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
-- =====================================================================================
|
-- =====================================================================================
|
||||||
-- Script: 03_MARS_835_verify_exports.sql
|
-- Script: 03_MARS_835_verify_exports.sql
|
||||||
-- Purpose: Verify exported files exist in DATA and HIST buckets after export
|
-- Purpose: Verify exported files exist in HIST bucket after export (HIST-only strategy)
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Created: 2025-12-17
|
-- Created: 2025-12-17
|
||||||
|
-- Updated: 2026-02-24 (Changed to HIST-only verification)
|
||||||
-- MARS Issue: MARS-835
|
-- MARS Issue: MARS-835
|
||||||
-- Target Locations: mrds_data_dev/ODS/CSDB/, mrds_hist_dev/ARCHIVE/CSDB/
|
-- Target Locations: mrds_hist_dev/ARCHIVE/CSDB/
|
||||||
-- =====================================================================================
|
-- =====================================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON SIZE UNLIMITED;
|
SET SERVEROUTPUT ON SIZE UNLIMITED;
|
||||||
@@ -13,17 +14,14 @@ SET VERIFY OFF;
|
|||||||
SET LINESIZE 200;
|
SET LINESIZE 200;
|
||||||
|
|
||||||
PROMPT =====================================================================================
|
PROMPT =====================================================================================
|
||||||
PROMPT MARS-835 Verification: Listing exported files in DATA and HIST buckets
|
PROMPT MARS-835 Verification: Listing exported files in HIST bucket (HIST-only strategy)
|
||||||
PROMPT =====================================================================================
|
PROMPT =====================================================================================
|
||||||
|
|
||||||
DECLARE
|
DECLARE
|
||||||
vDataBucketUri VARCHAR2(500);
|
|
||||||
vHistBucketUri VARCHAR2(500);
|
vHistBucketUri VARCHAR2(500);
|
||||||
vCredentialName VARCHAR2(100);
|
vCredentialName VARCHAR2(100);
|
||||||
vFileCount NUMBER := 0;
|
vFileCount NUMBER := 0;
|
||||||
vTotalDataFiles NUMBER := 0;
|
|
||||||
vTotalHistFiles NUMBER := 0;
|
vTotalHistFiles NUMBER := 0;
|
||||||
vTotalDataSize NUMBER := 0;
|
|
||||||
vTotalHistSize NUMBER := 0;
|
vTotalHistSize NUMBER := 0;
|
||||||
|
|
||||||
TYPE t_folder_info IS RECORD (
|
TYPE t_folder_info IS RECORD (
|
||||||
@@ -33,25 +31,18 @@ DECLARE
|
|||||||
);
|
);
|
||||||
TYPE t_folder_list IS TABLE OF t_folder_info;
|
TYPE t_folder_list IS TABLE OF t_folder_info;
|
||||||
|
|
||||||
vDataFolders t_folder_list;
|
|
||||||
vHistFolders t_folder_list;
|
vHistFolders t_folder_list;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get bucket URIs and credential from FILE_MANAGER
|
-- Get bucket URI and credential from FILE_MANAGER
|
||||||
vDataBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA');
|
|
||||||
vHistBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ARCHIVE');
|
vHistBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ARCHIVE');
|
||||||
vCredentialName := CT_MRDS.ENV_MANAGER.gvCredentialName;
|
vCredentialName := CT_MRDS.ENV_MANAGER.gvCredentialName;
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('VERIFICATION TIME: ' || TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.FF3'));
|
DBMS_OUTPUT.PUT_LINE('VERIFICATION TIME: ' || TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.FF3'));
|
||||||
DBMS_OUTPUT.PUT_LINE('DATA Bucket URI: ' || vDataBucketUri);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('HIST Bucket URI: ' || vHistBucketUri);
|
DBMS_OUTPUT.PUT_LINE('HIST Bucket URI: ' || vHistBucketUri);
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
|
||||||
-- Initialize folder lists
|
-- Initialize folder list (all tables in HIST)
|
||||||
vDataFolders := t_folder_list(
|
-- Initialize folder list (all 6 tables in HIST)
|
||||||
t_folder_info('ODS/CSDB/CSDB_DEBT/', 'DEBT', 'CSV'),
|
|
||||||
t_folder_info('ODS/CSDB/CSDB_DEBT_DAILY/', 'DEBT_DAILY', 'CSV')
|
|
||||||
);
|
|
||||||
|
|
||||||
vHistFolders := t_folder_list(
|
vHistFolders := t_folder_list(
|
||||||
t_folder_info('ARCHIVE/CSDB/CSDB_DEBT/', 'DEBT', 'Parquet'),
|
t_folder_info('ARCHIVE/CSDB/CSDB_DEBT/', 'DEBT', 'Parquet'),
|
||||||
t_folder_info('ARCHIVE/CSDB/CSDB_DEBT_DAILY/', 'DEBT_DAILY', 'Parquet'),
|
t_folder_info('ARCHIVE/CSDB/CSDB_DEBT_DAILY/', 'DEBT_DAILY', 'Parquet'),
|
||||||
@@ -62,49 +53,7 @@ BEGIN
|
|||||||
);
|
);
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
DBMS_OUTPUT.PUT_LINE('Checking DATA Bucket Exports (CSV format - last 6 months)');
|
DBMS_OUTPUT.PUT_LINE('Checking HIST Bucket Exports (Parquet with Hive partitioning - ALL data)');
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
|
||||||
|
|
||||||
-- Check DATA bucket exports
|
|
||||||
FOR i IN 1..vDataFolders.COUNT LOOP
|
|
||||||
vFileCount := 0;
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Table: ' || vDataFolders(i).table_name || ' (' || vDataFolders(i).expected_format || ')');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Folder: ' || vDataFolders(i).folder_name);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------');
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
FOR rec IN (
|
|
||||||
SELECT object_name, bytes, TO_CHAR(created, 'YYYY-MM-DD HH24:MI:SS') AS created_date
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => vCredentialName,
|
|
||||||
location_uri => vDataBucketUri || vDataFolders(i).folder_name
|
|
||||||
))
|
|
||||||
WHERE object_name LIKE '%.csv'
|
|
||||||
ORDER BY created DESC
|
|
||||||
) LOOP
|
|
||||||
vFileCount := vFileCount + 1;
|
|
||||||
vTotalDataFiles := vTotalDataFiles + 1;
|
|
||||||
vTotalDataSize := vTotalDataSize + rec.bytes;
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' [' || vFileCount || '] ' || rec.object_name ||
|
|
||||||
' (' || ROUND(rec.bytes/1024/1024, 2) || ' MB) - ' || rec.created_date);
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
IF vFileCount = 0 THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' [ERROR] No CSV files found - Export may have failed!');
|
|
||||||
ELSE
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' [SUCCESS] Found ' || vFileCount || ' CSV file(s)');
|
|
||||||
END IF;
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' [ERROR] Cannot access folder - ' || SQLERRM);
|
|
||||||
END;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Checking HIST Bucket Exports (Parquet with Hive partitioning)');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
|
|
||||||
-- Check HIST bucket exports
|
-- Check HIST bucket exports
|
||||||
@@ -155,24 +104,19 @@ BEGIN
|
|||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
DBMS_OUTPUT.PUT_LINE('Export Verification Summary');
|
DBMS_OUTPUT.PUT_LINE('Export Verification Summary');
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
DBMS_OUTPUT.PUT_LINE('DATA Bucket (CSV):');
|
DBMS_OUTPUT.PUT_LINE('HIST Bucket (Parquet - HIST-only strategy):');
|
||||||
DBMS_OUTPUT.PUT_LINE(' - Total files: ' || vTotalDataFiles);
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' - Total size: ' || ROUND(vTotalDataSize/1024/1024/1024, 2) || ' GB');
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' - Expected tables: 2 (DEBT, DEBT_DAILY - last 6 months)');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('HIST Bucket (Parquet):');
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' - Total files: ' || vTotalHistFiles || '+');
|
DBMS_OUTPUT.PUT_LINE(' - Total files: ' || vTotalHistFiles || '+');
|
||||||
DBMS_OUTPUT.PUT_LINE(' - Total size: ' || ROUND(vTotalHistSize/1024/1024/1024, 2) || '+ GB (sample)');
|
DBMS_OUTPUT.PUT_LINE(' - Total size: ' || ROUND(vTotalHistSize/1024/1024/1024, 2) || '+ GB (sample)');
|
||||||
DBMS_OUTPUT.PUT_LINE(' - Expected tables: 6 (all CSDB tables with historical data)');
|
DBMS_OUTPUT.PUT_LINE(' - Expected tables: 6 (all CSDB tables exported to HIST)');
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
|
||||||
IF vTotalDataFiles >= 2 AND vTotalHistFiles >= 6 THEN
|
IF vTotalHistFiles >= 6 THEN
|
||||||
DBMS_OUTPUT.PUT_LINE('[SUCCESS] OVERALL STATUS: Export appears SUCCESSFUL');
|
DBMS_OUTPUT.PUT_LINE('[SUCCESS] OVERALL STATUS: Export appears SUCCESSFUL');
|
||||||
DBMS_OUTPUT.PUT_LINE(' Files found in both DATA and HIST buckets');
|
DBMS_OUTPUT.PUT_LINE(' Files found in HIST bucket for all tables');
|
||||||
DBMS_OUTPUT.PUT_LINE(' Proceed to record count verification (Step 4)');
|
DBMS_OUTPUT.PUT_LINE(' Proceed to record count verification (Step 4)');
|
||||||
ELSIF vTotalDataFiles = 0 AND vTotalHistFiles = 0 THEN
|
ELSIF vTotalHistFiles = 0 THEN
|
||||||
DBMS_OUTPUT.PUT_LINE('[FAILED] OVERALL STATUS: Export FAILED');
|
DBMS_OUTPUT.PUT_LINE('[FAILED] OVERALL STATUS: Export FAILED');
|
||||||
DBMS_OUTPUT.PUT_LINE(' No files found in either bucket');
|
DBMS_OUTPUT.PUT_LINE(' No files found in HIST bucket');
|
||||||
DBMS_OUTPUT.PUT_LINE(' Review export logs for errors');
|
DBMS_OUTPUT.PUT_LINE(' Review export logs for errors');
|
||||||
ELSE
|
ELSE
|
||||||
DBMS_OUTPUT.PUT_LINE('[WARNING] OVERALL STATUS: Partial export detected');
|
DBMS_OUTPUT.PUT_LINE('[WARNING] OVERALL STATUS: Partial export detected');
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
-- =====================================================================================
|
-- =====================================================================================
|
||||||
-- Script: 04_MARS_835_verify_record_counts.sql
|
-- Script: 04_MARS_835_verify_record_counts.sql
|
||||||
-- Purpose: Verify record counts match between source tables and exported data
|
-- Purpose: Verify record counts match between source tables and exported data (HIST-only)
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Created: 2025-12-17
|
-- Created: 2025-12-17
|
||||||
|
-- Updated: 2026-02-24 (Changed to HIST-only verification)
|
||||||
-- MARS Issue: MARS-835
|
-- MARS Issue: MARS-835
|
||||||
-- Verification: Compare OU_CSDB source tables with ODS external tables
|
-- Verification: Compare OU_CSDB source tables with ODS external tables (HIST only)
|
||||||
-- =====================================================================================
|
-- =====================================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON SIZE UNLIMITED;
|
SET SERVEROUTPUT ON SIZE UNLIMITED;
|
||||||
@@ -13,28 +14,23 @@ SET VERIFY OFF;
|
|||||||
SET LINESIZE 200;
|
SET LINESIZE 200;
|
||||||
|
|
||||||
PROMPT =====================================================================================
|
PROMPT =====================================================================================
|
||||||
PROMPT MARS-835 Record Count Verification
|
PROMPT MARS-835 Record Count Verification (HIST-only strategy)
|
||||||
PROMPT =====================================================================================
|
PROMPT =====================================================================================
|
||||||
PROMPT Comparing source table counts with exported external table counts
|
PROMPT Comparing source table counts with HIST external table counts
|
||||||
PROMPT =====================================================================================
|
PROMPT =====================================================================================
|
||||||
|
|
||||||
DECLARE
|
DECLARE
|
||||||
TYPE t_table_info IS RECORD (
|
TYPE t_table_info IS RECORD (
|
||||||
source_schema VARCHAR2(50),
|
source_schema VARCHAR2(50),
|
||||||
source_table VARCHAR2(100),
|
source_table VARCHAR2(100),
|
||||||
data_external_table VARCHAR2(100),
|
hist_external_table VARCHAR2(100)
|
||||||
hist_external_table VARCHAR2(100),
|
|
||||||
has_data_export BOOLEAN,
|
|
||||||
has_hist_export BOOLEAN
|
|
||||||
);
|
);
|
||||||
TYPE t_table_list IS TABLE OF t_table_info;
|
TYPE t_table_list IS TABLE OF t_table_info;
|
||||||
|
|
||||||
vTables t_table_list;
|
vTables t_table_list;
|
||||||
vSourceCount NUMBER;
|
vSourceCount NUMBER;
|
||||||
vDataCount NUMBER;
|
|
||||||
vHistCount NUMBER;
|
vHistCount NUMBER;
|
||||||
vTotalSourceCount NUMBER := 0;
|
vTotalSourceCount NUMBER := 0;
|
||||||
vTotalDataCount NUMBER := 0;
|
|
||||||
vTotalHistCount NUMBER := 0;
|
vTotalHistCount NUMBER := 0;
|
||||||
vMismatchCount NUMBER := 0;
|
vMismatchCount NUMBER := 0;
|
||||||
vSql VARCHAR2(4000);
|
vSql VARCHAR2(4000);
|
||||||
@@ -42,18 +38,18 @@ BEGIN
|
|||||||
DBMS_OUTPUT.PUT_LINE('VERIFICATION TIME: ' || TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS'));
|
DBMS_OUTPUT.PUT_LINE('VERIFICATION TIME: ' || TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS'));
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
|
||||||
-- Initialize table list with export configuration
|
-- Initialize table list (all tables HIST-only)
|
||||||
vTables := t_table_list(
|
vTables := t_table_list(
|
||||||
t_table_info('OU_CSDB', 'LEGACY_DEBT', 'ODS.CSDB_DEBT_ODS', 'ODS.CSDB_DEBT_ARCHIVE', TRUE, TRUE),
|
t_table_info('OU_CSDB', 'LEGACY_DEBT', 'ODS.CSDB_DEBT_ARCHIVE'),
|
||||||
t_table_info('OU_CSDB', 'LEGACY_DEBT_DAILY', 'ODS.CSDB_DEBT_DAILY_ODS', 'ODS.CSDB_DEBT_DAILY_ARCHIVE', TRUE, TRUE),
|
t_table_info('OU_CSDB', 'LEGACY_DEBT_DAILY', 'ODS.CSDB_DEBT_DAILY_ARCHIVE'),
|
||||||
t_table_info('OU_CSDB', 'LEGACY_INSTR_RAT_FULL', NULL, 'ODS.CSDB_INSTR_RAT_FULL_ARCHIVE', FALSE, TRUE),
|
t_table_info('OU_CSDB', 'LEGACY_INSTR_RAT_FULL', 'ODS.CSDB_INSTR_RAT_FULL_ARCHIVE'),
|
||||||
t_table_info('OU_CSDB', 'LEGACY_INSTR_DESC_FULL', NULL, 'ODS.CSDB_INSTR_DESC_FULL_ARCHIVE', FALSE, TRUE),
|
t_table_info('OU_CSDB', 'LEGACY_INSTR_DESC_FULL', 'ODS.CSDB_INSTR_DESC_FULL_ARCHIVE'),
|
||||||
t_table_info('OU_CSDB', 'LEGACY_ISSUER_RAT_FULL', NULL, 'ODS.CSDB_ISSUER_RAT_FULL_ARCHIVE', FALSE, TRUE),
|
t_table_info('OU_CSDB', 'LEGACY_ISSUER_RAT_FULL', 'ODS.CSDB_ISSUER_RAT_FULL_ARCHIVE'),
|
||||||
t_table_info('OU_CSDB', 'LEGACY_ISSUER_DESC_FULL', NULL, 'ODS.CSDB_ISSUER_DESC_FULL_ARCHIVE', FALSE, TRUE)
|
t_table_info('OU_CSDB', 'LEGACY_ISSUER_DESC_FULL', 'ODS.CSDB_ISSUER_DESC_FULL_ARCHIVE')
|
||||||
);
|
);
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('-----------------------------------------------------------------------------------------');
|
DBMS_OUTPUT.PUT_LINE('-----------------------------------------------------------------------------------------');
|
||||||
DBMS_OUTPUT.PUT_LINE('Table Name Source Count DATA Count HIST Count Status');
|
DBMS_OUTPUT.PUT_LINE('Table Name Source Count HIST Count Status');
|
||||||
DBMS_OUTPUT.PUT_LINE('-----------------------------------------------------------------------------------------');
|
DBMS_OUTPUT.PUT_LINE('-----------------------------------------------------------------------------------------');
|
||||||
|
|
||||||
FOR i IN 1..vTables.COUNT LOOP
|
FOR i IN 1..vTables.COUNT LOOP
|
||||||
@@ -70,31 +66,6 @@ BEGIN
|
|||||||
CONTINUE;
|
CONTINUE;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
-- Get DATA external table count (if applicable)
|
|
||||||
IF vTables(i).has_data_export THEN
|
|
||||||
vSql := 'SELECT COUNT(*) FROM ' || vTables(i).data_external_table;
|
|
||||||
BEGIN
|
|
||||||
EXECUTE IMMEDIATE vSql INTO vDataCount;
|
|
||||||
vTotalDataCount := vTotalDataCount + vDataCount;
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
-- If source table is empty (0 records), no files were exported
|
|
||||||
-- External table returns error, treat as 0
|
|
||||||
-- Acceptable error codes:
|
|
||||||
-- ORA-29913: error in executing ODCIEXTTABLEOPEN callout
|
|
||||||
-- ORA-29400: data cartridge error
|
|
||||||
-- KUP-13023: nothing matched wildcard query (no files in bucket)
|
|
||||||
-- NOTE: ORA-30653 (reject limit) is a real data quality error, not treated as empty
|
|
||||||
IF vSourceCount = 0 OR SQLCODE IN (-29913, -29400) OR SQLERRM LIKE '%KUP-13023%' THEN
|
|
||||||
vDataCount := 0;
|
|
||||||
ELSE
|
|
||||||
vDataCount := -1;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
ELSE
|
|
||||||
vDataCount := NULL;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Get HIST external table count
|
-- Get HIST external table count
|
||||||
vSql := 'SELECT COUNT(*) FROM ' || vTables(i).hist_external_table;
|
vSql := 'SELECT COUNT(*) FROM ' || vTables(i).hist_external_table;
|
||||||
BEGIN
|
BEGIN
|
||||||
@@ -119,18 +90,8 @@ BEGIN
|
|||||||
-- Display results
|
-- Display results
|
||||||
DECLARE
|
DECLARE
|
||||||
vStatus VARCHAR2(20);
|
vStatus VARCHAR2(20);
|
||||||
vDataDisplay VARCHAR2(17);
|
|
||||||
vHistDisplay VARCHAR2(17);
|
vHistDisplay VARCHAR2(17);
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Format DATA count display
|
|
||||||
IF vDataCount IS NULL THEN
|
|
||||||
vDataDisplay := 'N/A';
|
|
||||||
ELSIF vDataCount = -1 THEN
|
|
||||||
vDataDisplay := 'ERROR';
|
|
||||||
ELSE
|
|
||||||
vDataDisplay := TO_CHAR(vDataCount, '9,999,999,999');
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Format HIST count display
|
-- Format HIST count display
|
||||||
IF vHistCount = -1 THEN
|
IF vHistCount = -1 THEN
|
||||||
vHistDisplay := 'ERROR';
|
vHistDisplay := 'ERROR';
|
||||||
@@ -138,35 +99,20 @@ BEGIN
|
|||||||
vHistDisplay := TO_CHAR(vHistCount, '9,999,999,999');
|
vHistDisplay := TO_CHAR(vHistCount, '9,999,999,999');
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Determine status
|
-- Determine status (HIST only: check HIST = SOURCE)
|
||||||
IF vTables(i).has_data_export THEN
|
IF vHistCount = vSourceCount THEN
|
||||||
-- Split export: check DATA + HIST = SOURCE
|
vStatus := 'PASS';
|
||||||
IF (vDataCount + vHistCount) = vSourceCount THEN
|
ELSIF vHistCount = -1 THEN
|
||||||
vStatus := 'PASS';
|
vStatus := 'ERROR';
|
||||||
ELSIF vDataCount = -1 OR vHistCount = -1 THEN
|
vMismatchCount := vMismatchCount + 1;
|
||||||
vStatus := 'ERROR';
|
|
||||||
vMismatchCount := vMismatchCount + 1;
|
|
||||||
ELSE
|
|
||||||
vStatus := 'MISMATCH';
|
|
||||||
vMismatchCount := vMismatchCount + 1;
|
|
||||||
END IF;
|
|
||||||
ELSE
|
ELSE
|
||||||
-- HIST only: check HIST = SOURCE
|
vStatus := 'MISMATCH';
|
||||||
IF vHistCount = vSourceCount THEN
|
vMismatchCount := vMismatchCount + 1;
|
||||||
vStatus := 'PASS';
|
|
||||||
ELSIF vHistCount = -1 THEN
|
|
||||||
vStatus := 'ERROR';
|
|
||||||
vMismatchCount := vMismatchCount + 1;
|
|
||||||
ELSE
|
|
||||||
vStatus := 'MISMATCH';
|
|
||||||
vMismatchCount := vMismatchCount + 1;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE(
|
DBMS_OUTPUT.PUT_LINE(
|
||||||
RPAD(vTables(i).source_table, 24) ||
|
RPAD(vTables(i).source_table, 24) ||
|
||||||
LPAD(TO_CHAR(vSourceCount, '9,999,999,999'), 15) ||
|
LPAD(TO_CHAR(vSourceCount, '9,999,999,999'), 15) ||
|
||||||
LPAD(vDataDisplay, 15) ||
|
|
||||||
LPAD(vHistDisplay, 15) || ' ' ||
|
LPAD(vHistDisplay, 15) || ' ' ||
|
||||||
vStatus
|
vStatus
|
||||||
);
|
);
|
||||||
@@ -177,18 +123,16 @@ BEGIN
|
|||||||
DBMS_OUTPUT.PUT_LINE(
|
DBMS_OUTPUT.PUT_LINE(
|
||||||
RPAD('TOTALS', 24) ||
|
RPAD('TOTALS', 24) ||
|
||||||
LPAD(TO_CHAR(vTotalSourceCount, '9,999,999,999'), 15) ||
|
LPAD(TO_CHAR(vTotalSourceCount, '9,999,999,999'), 15) ||
|
||||||
LPAD(TO_CHAR(vTotalDataCount, '9,999,999,999'), 15) ||
|
|
||||||
LPAD(TO_CHAR(vTotalHistCount, '9,999,999,999'), 15)
|
LPAD(TO_CHAR(vTotalHistCount, '9,999,999,999'), 15)
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE('-----------------------------------------------------------------------------------------');
|
DBMS_OUTPUT.PUT_LINE('-----------------------------------------------------------------------------------------');
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
DBMS_OUTPUT.PUT_LINE('Record Count Verification Summary');
|
DBMS_OUTPUT.PUT_LINE('Record Count Verification Summary (HIST-only strategy)');
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
DBMS_OUTPUT.PUT_LINE('Total source records: ' || TO_CHAR(vTotalSourceCount, '9,999,999,999'));
|
DBMS_OUTPUT.PUT_LINE('Total source records: ' || TO_CHAR(vTotalSourceCount, '9,999,999,999'));
|
||||||
DBMS_OUTPUT.PUT_LINE('Total DATA records: ' || TO_CHAR(vTotalDataCount, '9,999,999,999') || ' (last 6 months)');
|
DBMS_OUTPUT.PUT_LINE('Total HIST records: ' || TO_CHAR(vTotalHistCount, '9,999,999,999') || ' (all data in HIST)');
|
||||||
DBMS_OUTPUT.PUT_LINE('Total HIST records: ' || TO_CHAR(vTotalHistCount, '9,999,999,999') || ' (historical + full exports)');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
|
||||||
IF vMismatchCount = 0 THEN
|
IF vMismatchCount = 0 THEN
|
||||||
@@ -209,7 +153,6 @@ BEGIN
|
|||||||
DBMS_OUTPUT.PUT_LINE(' MISMATCH - Record counts differ (may be pre-existing files or export issue)');
|
DBMS_OUTPUT.PUT_LINE(' MISMATCH - Record counts differ (may be pre-existing files or export issue)');
|
||||||
DBMS_OUTPUT.PUT_LINE(' Check pre-check results to identify pre-existing files');
|
DBMS_OUTPUT.PUT_LINE(' Check pre-check results to identify pre-existing files');
|
||||||
DBMS_OUTPUT.PUT_LINE(' ERROR - Cannot access table (may not exist yet)');
|
DBMS_OUTPUT.PUT_LINE(' ERROR - Cannot access table (may not exist yet)');
|
||||||
DBMS_OUTPUT.PUT_LINE(' N/A - Not applicable (table not exported to DATA)');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
|
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
--=============================================================================================================================
|
||||||
|
-- MARS-835 ROLLBACK: Delete File Registration Records
|
||||||
|
--=============================================================================================================================
|
||||||
|
-- Purpose: Delete all file registration records from A_SOURCE_FILE_RECEIVED table for MARS-835 process
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-13
|
||||||
|
-- Related: MARS-835 - CSDB Data Export Rollback
|
||||||
|
--=============================================================================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
SET TIMING ON
|
||||||
|
|
||||||
|
PROMPT ========================================================================
|
||||||
|
PROMPT ROLLBACK: Deleting file registration records from A_SOURCE_FILE_RECEIVED
|
||||||
|
PROMPT ========================================================================
|
||||||
|
|
||||||
|
DECLARE
|
||||||
|
vRowCount NUMBER := 0;
|
||||||
|
vStartTime TIMESTAMP := SYSTIMESTAMP;
|
||||||
|
vEndTime TIMESTAMP;
|
||||||
|
vElapsedSeconds NUMBER;
|
||||||
|
BEGIN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Deleting all MARS-835 file registrations from A_SOURCE_FILE_RECEIVED...');
|
||||||
|
|
||||||
|
-- Delete all records for MARS-835 process
|
||||||
|
DELETE FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE PROCESS_NAME = 'MARS-835';
|
||||||
|
|
||||||
|
vRowCount := SQL%ROWCOUNT;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
vEndTime := SYSTIMESTAMP;
|
||||||
|
vElapsedSeconds := EXTRACT(SECOND FROM (vEndTime - vStartTime)) +
|
||||||
|
EXTRACT(MINUTE FROM (vEndTime - vStartTime)) * 60 +
|
||||||
|
EXTRACT(HOUR FROM (vEndTime - vStartTime)) * 3600;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('========================================================================');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: File registration records deleted');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('========================================================================');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Records deleted: ' || vRowCount);
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Elapsed time: ' || ROUND(vElapsedSeconds, 2) || ' seconds');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('========================================================================');
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
ROLLBACK;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('ERROR: Failed to delete file registration records');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM);
|
||||||
|
RAISE;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
--=============================================================================================================================
|
||||||
|
-- End of Script
|
||||||
|
--=============================================================================================================================
|
||||||
@@ -1,76 +1,43 @@
|
|||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- MARS-835 ROLLBACK: Delete Group 1 Exported Files (DEBT, DEBT_DAILY)
|
-- MARS-835 ROLLBACK: Delete Group 1 Exported Files (DEBT, DEBT_DAILY)
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- Purpose: Delete exported CSV and Parquet files from DATA and HIST buckets
|
-- Purpose: Delete exported Parquet files from HIST bucket (ARCHIVE only)
|
||||||
-- WARNING: This will permanently delete exported data files!
|
-- WARNING: This will permanently delete exported data files!
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-12-17
|
-- Date: 2025-12-17
|
||||||
|
-- Updated: 2026-02-24 (Changed to HIST-only rollback, no DATA bucket)
|
||||||
-- Related: MARS-835 - CSDB Data Export Rollback
|
-- Related: MARS-835 - CSDB Data Export Rollback
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON SIZE UNLIMITED
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT ROLLBACK: Deleting DEBT exported files
|
PROMPT ROLLBACK: Deleting DEBT exported files from HIST
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT WARNING: This will delete files from:
|
PROMPT WARNING: This will delete files from:
|
||||||
PROMPT - DATA bucket: mrds_data_dev/ODS/CSDB/CSDB_DEBT/
|
|
||||||
PROMPT - HIST bucket: mrds_hist_dev/ARCHIVE/CSDB/CSDB_DEBT/
|
PROMPT - HIST bucket: mrds_hist_dev/ARCHIVE/CSDB/CSDB_DEBT/
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
|
|
||||||
DECLARE
|
DECLARE
|
||||||
vDataBucketUri VARCHAR2(500);
|
|
||||||
vHistBucketUri VARCHAR2(500);
|
vHistBucketUri VARCHAR2(500);
|
||||||
vCredentialName VARCHAR2(100);
|
vCredentialName VARCHAR2(100);
|
||||||
|
vFileCount NUMBER := 0;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get bucket URIs and credential
|
-- Get bucket URI and credential
|
||||||
vDataBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA');
|
|
||||||
vHistBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ARCHIVE');
|
vHistBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ARCHIVE');
|
||||||
vCredentialName := CT_MRDS.ENV_MANAGER.gvCredentialName;
|
vCredentialName := CT_MRDS.ENV_MANAGER.gvCredentialName;
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Deleting DEBT files from DATA bucket...');
|
DBMS_OUTPUT.PUT_LINE('Deleting DEBT Parquet files from ARCHIVE bucket...');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Using DBMS_CLOUD.LIST_OBJECTS');
|
||||||
|
|
||||||
-- Delete CSV files from DATA bucket (only files matching export pattern)
|
-- Delete Parquet files from ARCHIVE bucket using DBMS_CLOUD.LIST_OBJECTS
|
||||||
-- Pattern matches: LEGACY_DEBT_YYYYMM.csv OR LEGACY_DEBT_YYYYMM_1_20260122T...Z.csv (Oracle timestamp)
|
|
||||||
FOR rec IN (
|
FOR rec IN (
|
||||||
SELECT object_name
|
SELECT object_name
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => vCredentialName,
|
|
||||||
location_uri => vDataBucketUri || 'ODS/CSDB/CSDB_DEBT/'
|
|
||||||
))
|
|
||||||
WHERE object_name LIKE 'LEGACY_DEBT_%'
|
|
||||||
AND object_name LIKE '%.csv'
|
|
||||||
AND REGEXP_LIKE(object_name, '^LEGACY_DEBT_[0-9]{6}(_[0-9]+_[0-9]{8}T[0-9]{6,}Z)?\.csv$') -- YYYYMM or YYYYMM_1_timestamp
|
|
||||||
) LOOP
|
|
||||||
BEGIN
|
|
||||||
DBMS_CLOUD.DELETE_OBJECT(
|
|
||||||
credential_name => vCredentialName,
|
|
||||||
object_uri => vDataBucketUri || 'ODS/CSDB/CSDB_DEBT/' || rec.object_name
|
|
||||||
);
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' Deleted: ' || rec.object_name);
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
IF SQLCODE = -20404 THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' Skipped (not found): ' || rec.object_name);
|
|
||||||
ELSE
|
|
||||||
RAISE;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Deleting DEBT files from HIST bucket...');
|
|
||||||
|
|
||||||
-- Delete Parquet files from HIST bucket (only files matching export pattern)
|
|
||||||
-- Pattern matches: YYYYMM.parquet OR YYYYMM_1_20260122T...Z.parquet (Oracle timestamp)
|
|
||||||
FOR rec IN (
|
|
||||||
SELECT object_name
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
||||||
credential_name => vCredentialName,
|
credential_name => vCredentialName,
|
||||||
location_uri => vHistBucketUri || 'ARCHIVE/CSDB/CSDB_DEBT/'
|
location_uri => vHistBucketUri || 'ARCHIVE/CSDB/CSDB_DEBT/'
|
||||||
))
|
))
|
||||||
WHERE object_name LIKE '%PARTITION_YEAR=%' -- Hive-style partitioning folders
|
WHERE object_name NOT LIKE '%/' -- Exclude directories
|
||||||
AND object_name LIKE '%.parquet'
|
|
||||||
AND REGEXP_LIKE(object_name, '[0-9]{6}(_[0-9]+_[0-9]{8}T[0-9]{6,}Z)?\.parquet$') -- YYYYMM or YYYYMM_1_timestamp
|
|
||||||
) LOOP
|
) LOOP
|
||||||
BEGIN
|
BEGIN
|
||||||
DBMS_CLOUD.DELETE_OBJECT(
|
DBMS_CLOUD.DELETE_OBJECT(
|
||||||
@@ -78,6 +45,7 @@ BEGIN
|
|||||||
object_uri => vHistBucketUri || 'ARCHIVE/CSDB/CSDB_DEBT/' || rec.object_name
|
object_uri => vHistBucketUri || 'ARCHIVE/CSDB/CSDB_DEBT/' || rec.object_name
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE(' Deleted: ' || rec.object_name);
|
DBMS_OUTPUT.PUT_LINE(' Deleted: ' || rec.object_name);
|
||||||
|
vFileCount := vFileCount + 1;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
IF SQLCODE = -20404 THEN
|
IF SQLCODE = -20404 THEN
|
||||||
@@ -88,71 +56,41 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: DEBT files deleted');
|
IF vFileCount = 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' INFO: No DEBT Parquet files found to delete');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: DEBT Parquet files deleted from ARCHIVE bucket (' || vFileCount || ' file(s))');
|
||||||
END;
|
END;
|
||||||
/
|
/
|
||||||
|
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT ROLLBACK: Deleting DEBT_DAILY exported files
|
PROMPT ROLLBACK: Deleting DEBT_DAILY exported files from HIST
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT WARNING: This will delete files from:
|
PROMPT WARNING: This will delete files from:
|
||||||
PROMPT - DATA bucket: mrds_data_dev/ODS/CSDB/CSDB_DEBT_DAILY/
|
|
||||||
PROMPT - HIST bucket: mrds_hist_dev/ARCHIVE/CSDB/CSDB_DEBT_DAILY/
|
PROMPT - HIST bucket: mrds_hist_dev/ARCHIVE/CSDB/CSDB_DEBT_DAILY/
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
|
|
||||||
DECLARE
|
DECLARE
|
||||||
vDataBucketUri VARCHAR2(500);
|
|
||||||
vHistBucketUri VARCHAR2(500);
|
vHistBucketUri VARCHAR2(500);
|
||||||
vCredentialName VARCHAR2(100);
|
vCredentialName VARCHAR2(100);
|
||||||
|
vFileCount NUMBER := 0;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get bucket URIs and credential
|
-- Get bucket URI and credential
|
||||||
vDataBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA');
|
|
||||||
vHistBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ARCHIVE');
|
vHistBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ARCHIVE');
|
||||||
vCredentialName := CT_MRDS.ENV_MANAGER.gvCredentialName;
|
vCredentialName := CT_MRDS.ENV_MANAGER.gvCredentialName;
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Deleting DEBT_DAILY files from DATA bucket...');
|
DBMS_OUTPUT.PUT_LINE('Deleting DEBT_DAILY Parquet files from ARCHIVE bucket...');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Using DBMS_CLOUD.LIST_OBJECTS');
|
||||||
|
|
||||||
-- Delete CSV files from DATA bucket (only files matching export pattern)
|
-- Delete Parquet files from ARCHIVE bucket using DBMS_CLOUD.LIST_OBJECTS
|
||||||
-- Pattern matches: LEGACY_DEBT_DAILY_YYYYMM.csv OR LEGACY_DEBT_DAILY_YYYYMM_1_timestamp.csv
|
|
||||||
FOR rec IN (
|
FOR rec IN (
|
||||||
SELECT object_name
|
SELECT object_name
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => vCredentialName,
|
|
||||||
location_uri => vDataBucketUri || 'ODS/CSDB/CSDB_DEBT_DAILY/'
|
|
||||||
))
|
|
||||||
WHERE object_name LIKE 'LEGACY_DEBT_DAILY_%'
|
|
||||||
AND object_name LIKE '%.csv'
|
|
||||||
AND REGEXP_LIKE(object_name, '^LEGACY_DEBT_DAILY_[0-9]{6}(_[0-9]+_[0-9]{8}T[0-9]{6,}Z)?\.csv$') -- YYYYMM or YYYYMM_1_timestamp
|
|
||||||
) LOOP
|
|
||||||
BEGIN
|
|
||||||
DBMS_CLOUD.DELETE_OBJECT(
|
|
||||||
credential_name => vCredentialName,
|
|
||||||
object_uri => vDataBucketUri || 'ODS/CSDB/CSDB_DEBT_DAILY/' || rec.object_name
|
|
||||||
);
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' Deleted: ' || rec.object_name);
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
IF SQLCODE = -20404 THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' Skipped (not found): ' || rec.object_name);
|
|
||||||
ELSE
|
|
||||||
RAISE;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Deleting DEBT_DAILY files from HIST bucket...');
|
|
||||||
|
|
||||||
-- Delete Parquet files from HIST bucket (only files matching export pattern)
|
|
||||||
-- Pattern matches: YYYYMM.parquet OR YYYYMM_1_timestamp.parquet
|
|
||||||
FOR rec IN (
|
|
||||||
SELECT object_name
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
||||||
credential_name => vCredentialName,
|
credential_name => vCredentialName,
|
||||||
location_uri => vHistBucketUri || 'ARCHIVE/CSDB/CSDB_DEBT_DAILY/'
|
location_uri => vHistBucketUri || 'ARCHIVE/CSDB/CSDB_DEBT_DAILY/'
|
||||||
))
|
))
|
||||||
WHERE object_name LIKE '%PARTITION_YEAR=%' -- Hive-style partitioning folders
|
WHERE object_name NOT LIKE '%/' -- Exclude directories
|
||||||
AND object_name LIKE '%.parquet'
|
|
||||||
AND REGEXP_LIKE(object_name, '[0-9]{6}(_[0-9]+_[0-9]{8}T[0-9]{6,}Z)?\.parquet$') -- YYYYMM or YYYYMM_1_timestamp
|
|
||||||
) LOOP
|
) LOOP
|
||||||
BEGIN
|
BEGIN
|
||||||
DBMS_CLOUD.DELETE_OBJECT(
|
DBMS_CLOUD.DELETE_OBJECT(
|
||||||
@@ -160,6 +98,7 @@ BEGIN
|
|||||||
object_uri => vHistBucketUri || 'ARCHIVE/CSDB/CSDB_DEBT_DAILY/' || rec.object_name
|
object_uri => vHistBucketUri || 'ARCHIVE/CSDB/CSDB_DEBT_DAILY/' || rec.object_name
|
||||||
);
|
);
|
||||||
DBMS_OUTPUT.PUT_LINE(' Deleted: ' || rec.object_name);
|
DBMS_OUTPUT.PUT_LINE(' Deleted: ' || rec.object_name);
|
||||||
|
vFileCount := vFileCount + 1;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
IF SQLCODE = -20404 THEN
|
IF SQLCODE = -20404 THEN
|
||||||
@@ -170,7 +109,11 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('SUCCESS: DEBT_DAILY files deleted');
|
IF vFileCount = 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' INFO: No DEBT_DAILY Parquet files found to delete');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: DEBT_DAILY Parquet files deleted from ARCHIVE bucket (' || vFileCount || ' file(s))');
|
||||||
END;
|
END;
|
||||||
/
|
/
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
-- =====================================================================================
|
-- =====================================================================================
|
||||||
-- Script: 99_MARS_835_verify_rollback.sql
|
-- Script: 99_MARS_835_verify_rollback.sql
|
||||||
-- Purpose: Verify all exported files have been deleted from DATA and HIST buckets
|
-- Purpose: Verify all exported files have been deleted from HIST bucket (HIST-only strategy)
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Created: 2025-12-17
|
-- Created: 2025-12-17
|
||||||
|
-- Updated: 2026-02-24 (Changed to HIST-only verification)
|
||||||
-- MARS Issue: MARS-835
|
-- MARS Issue: MARS-835
|
||||||
-- Verification: Confirm complete rollback (no CSDB files remaining)
|
-- Verification: Confirm complete rollback (no CSDB files remaining in HIST)
|
||||||
-- =====================================================================================
|
-- =====================================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON SIZE UNLIMITED;
|
SET SERVEROUTPUT ON SIZE UNLIMITED;
|
||||||
@@ -19,33 +20,23 @@ PROMPT Checking that all CSDB export files have been deleted
|
|||||||
PROMPT =====================================================================================
|
PROMPT =====================================================================================
|
||||||
|
|
||||||
DECLARE
|
DECLARE
|
||||||
vDataBucketUri VARCHAR2(500);
|
|
||||||
vHistBucketUri VARCHAR2(500);
|
vHistBucketUri VARCHAR2(500);
|
||||||
vCredentialName VARCHAR2(100);
|
vCredentialName VARCHAR2(100);
|
||||||
vDataFileCount NUMBER := 0;
|
|
||||||
vHistFileCount NUMBER := 0;
|
vHistFileCount NUMBER := 0;
|
||||||
vTotalFiles NUMBER := 0;
|
|
||||||
|
|
||||||
TYPE t_folder_list IS TABLE OF VARCHAR2(200);
|
TYPE t_folder_list IS TABLE OF VARCHAR2(200);
|
||||||
vDataFolders t_folder_list;
|
|
||||||
vHistFolders t_folder_list;
|
vHistFolders t_folder_list;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get bucket URIs
|
-- Get bucket URI
|
||||||
vDataBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('DATA');
|
|
||||||
vHistBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ARCHIVE');
|
vHistBucketUri := CT_MRDS.FILE_MANAGER.GET_BUCKET_URI('ARCHIVE');
|
||||||
vCredentialName := CT_MRDS.ENV_MANAGER.gvCredentialName;
|
vCredentialName := CT_MRDS.ENV_MANAGER.gvCredentialName;
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('ROLLBACK VERIFICATION TIME: ' || TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.FF3'));
|
DBMS_OUTPUT.PUT_LINE('ROLLBACK VERIFICATION TIME: ' || TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS.FF3'));
|
||||||
DBMS_OUTPUT.PUT_LINE('DATA Bucket URI: ' || vDataBucketUri);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('HIST Bucket URI: ' || vHistBucketUri);
|
DBMS_OUTPUT.PUT_LINE('HIST Bucket URI: ' || vHistBucketUri);
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
|
||||||
-- Initialize folder lists
|
-- Initialize folder list (all 6 tables in HIST)
|
||||||
vDataFolders := t_folder_list(
|
-- Initialize folder list (all 6 tables in HIST)
|
||||||
'ODS/CSDB/CSDB_DEBT/',
|
|
||||||
'ODS/CSDB/CSDB_DEBT_DAILY/'
|
|
||||||
);
|
|
||||||
|
|
||||||
vHistFolders := t_folder_list(
|
vHistFolders := t_folder_list(
|
||||||
'ARCHIVE/CSDB/CSDB_DEBT/',
|
'ARCHIVE/CSDB/CSDB_DEBT/',
|
||||||
'ARCHIVE/CSDB/CSDB_DEBT_DAILY/',
|
'ARCHIVE/CSDB/CSDB_DEBT_DAILY/',
|
||||||
@@ -55,47 +46,6 @@ BEGIN
|
|||||||
'ARCHIVE/CSDB/CSDB_ISSUER_DESC_FULL/'
|
'ARCHIVE/CSDB/CSDB_ISSUER_DESC_FULL/'
|
||||||
);
|
);
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Checking DATA Bucket (should be empty)');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
|
||||||
|
|
||||||
-- Check DATA bucket
|
|
||||||
FOR i IN 1..vDataFolders.COUNT LOOP
|
|
||||||
DECLARE
|
|
||||||
vCount NUMBER := 0;
|
|
||||||
BEGIN
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('Folder: ' || vDataFolders(i));
|
|
||||||
|
|
||||||
FOR rec IN (
|
|
||||||
SELECT object_name
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => vCredentialName,
|
|
||||||
location_uri => vDataBucketUri || vDataFolders(i)
|
|
||||||
))
|
|
||||||
WHERE object_name LIKE '%.csv'
|
|
||||||
) LOOP
|
|
||||||
vCount := vCount + 1;
|
|
||||||
vDataFileCount := vDataFileCount + 1;
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' [FOUND] ' || rec.object_name);
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
IF vCount = 0 THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' [OK] No CSV files found');
|
|
||||||
ELSE
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' [INFO] Found ' || vCount || ' file(s) - may be pre-existing files from before installation');
|
|
||||||
END IF;
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
IF SQLCODE = -20404 THEN
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' [OK] Folder does not exist or is empty');
|
|
||||||
ELSE
|
|
||||||
DBMS_OUTPUT.PUT_LINE(' [ERROR] ' || SQLERRM);
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
DBMS_OUTPUT.PUT_LINE('Checking HIST Bucket (should be empty)');
|
DBMS_OUTPUT.PUT_LINE('Checking HIST Bucket (should be empty)');
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
@@ -139,24 +89,21 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
vTotalFiles := vDataFileCount + vHistFileCount;
|
|
||||||
|
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
DBMS_OUTPUT.PUT_LINE('Rollback Verification Summary');
|
DBMS_OUTPUT.PUT_LINE('Rollback Verification Summary');
|
||||||
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
DBMS_OUTPUT.PUT_LINE('=====================================================================================');
|
||||||
DBMS_OUTPUT.PUT_LINE('DATA bucket files remaining: ' || vDataFileCount);
|
|
||||||
DBMS_OUTPUT.PUT_LINE('HIST bucket files remaining: ' || vHistFileCount || '+');
|
DBMS_OUTPUT.PUT_LINE('HIST bucket files remaining: ' || vHistFileCount || '+');
|
||||||
DBMS_OUTPUT.PUT_LINE('Total files found: ' || vTotalFiles || '+');
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
DBMS_OUTPUT.PUT_LINE('');
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
|
||||||
IF vTotalFiles = 0 THEN
|
IF vHistFileCount = 0 THEN
|
||||||
DBMS_OUTPUT.PUT_LINE('[PASSED] ROLLBACK VERIFICATION PASSED');
|
DBMS_OUTPUT.PUT_LINE('[PASSED] ROLLBACK VERIFICATION PASSED');
|
||||||
DBMS_OUTPUT.PUT_LINE(' All CSDB export files have been deleted or were not created');
|
DBMS_OUTPUT.PUT_LINE(' All CSDB export files have been deleted or were not created');
|
||||||
DBMS_OUTPUT.PUT_LINE(' Buckets are clean and ready for re-export if needed');
|
DBMS_OUTPUT.PUT_LINE(' HIST bucket is clean and ready for re-export if needed');
|
||||||
ELSE
|
ELSE
|
||||||
DBMS_OUTPUT.PUT_LINE('[INFO] ROLLBACK VERIFICATION COMPLETED');
|
DBMS_OUTPUT.PUT_LINE('[INFO] ROLLBACK VERIFICATION COMPLETED');
|
||||||
DBMS_OUTPUT.PUT_LINE(' Found ' || vTotalFiles || '+ file(s) remaining in buckets');
|
DBMS_OUTPUT.PUT_LINE(' Found ' || vHistFileCount || '+ file(s) remaining in HIST bucket');
|
||||||
DBMS_OUTPUT.PUT_LINE(' NOTE: These may be pre-existing files from before installation.');
|
DBMS_OUTPUT.PUT_LINE(' NOTE: These may be pre-existing files from before installation.');
|
||||||
DBMS_OUTPUT.PUT_LINE(' Rollback only deletes files created during this export operation.');
|
DBMS_OUTPUT.PUT_LINE(' Rollback only deletes files created during this export operation.');
|
||||||
DBMS_OUTPUT.PUT_LINE(' If needed, manually verify and clean up remaining files.');
|
DBMS_OUTPUT.PUT_LINE(' If needed, manually verify and clean up remaining files.');
|
||||||
|
|||||||
@@ -1,165 +0,0 @@
|
|||||||
# MARS-835: One-Time CSDB Data Export from Operational Database to External Tables
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
This package performs a one-time bulk export of CSDB data from operational database tables (OU_CSDB schema) to new external tables in OCI buckets. The export uses DATA_EXPORTER v2.4.0 with per-column date format handling to move historical data to either DATA bucket (CSV format) or HIST bucket (Parquet format with Hive-style partitioning).
|
|
||||||
|
|
||||||
**Migration Strategy:**
|
|
||||||
- **Split Export (2 tables)**: DEBT, DEBT_DAILY - Last 6 months → DATA (CSV), Older data → HIST (Parquet)
|
|
||||||
- **HIST Only (4 tables)**: INSTR_RAT_FULL, INSTR_DESC_FULL, ISSUER_RAT_FULL, ISSUER_DESC_FULL - All data → HIST (Parquet)
|
|
||||||
|
|
||||||
**Key Transformations:**
|
|
||||||
- Column rename: `A_ETL_LOAD_SET_FK` → `A_WORKFLOW_HISTORY_KEY` (all tables)
|
|
||||||
- Column removal: DEBT (2 columns), DEBT_DAILY (6 columns) not required in new structure
|
|
||||||
|
|
||||||
## Contents
|
|
||||||
- `install_mars835.sql` - Master installation script with SPOOL logging
|
|
||||||
- `rollback_mars835.sql` - Master rollback script
|
|
||||||
- `01_MARS_835_*.sql` - Individual installation scripts
|
|
||||||
- `91_MARS_835_*.sql` - Individual rollback scripts
|
|
||||||
- `track_package_versions.sql` - Package version tracking
|
|
||||||
- `verify_packages_version.sql` - Package verification
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
- Oracle Database 23ai
|
|
||||||
- ADMIN user access (required for all MARS installations)
|
|
||||||
- ENV_MANAGER v3.1.0+
|
|
||||||
- Required schema privileges
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### Option 1: Master Script (Recommended)
|
|
||||||
```powershell
|
|
||||||
# IMPORTANT: Execute as ADMIN user for proper privilege management
|
|
||||||
Get-Content "MARS_Packages/REL01_POST_DEACTIVATION/MARS-835/install_mars835.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
|
|
||||||
|
|
||||||
# Log file created: log/INSTALL_MARS_835_<PDB>_<timestamp>.log
|
|
||||||
```
|
|
||||||
|
|
||||||
### Option 2: Individual Scripts
|
|
||||||
```powershell
|
|
||||||
# IMPORTANT: Execute as ADMIN user
|
|
||||||
Get-Content "01_MARS_835_*.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
|
|
||||||
Get-Content "02_MARS_835_*.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
|
|
||||||
# ... etc
|
|
||||||
```
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
```sql
|
|
||||||
-- Verify package versions
|
|
||||||
SELECT PACKAGE_NAME.GET_VERSION() FROM DUAL;
|
|
||||||
|
|
||||||
-- Check for errors (ADMIN user checks specific schema)
|
|
||||||
SELECT * FROM ALL_ERRORS
|
|
||||||
WHERE OWNER = 'CT_MRDS' -- Replace with target schema
|
|
||||||
AND NAME = 'PACKAGE_NAME';
|
|
||||||
|
|
||||||
-- Verify no untracked changes
|
|
||||||
SELECT ENV_MANAGER.CHECK_PACKAGE_CHANGES('CT_MRDS', 'PACKAGE_NAME') FROM DUAL;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Rollback
|
|
||||||
```powershell
|
|
||||||
# IMPORTANT: Execute as ADMIN user
|
|
||||||
Get-Content "MARS_Packages/REL01_POST_DEACTIVATION/MARS-835/rollback_mars835.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
|
|
||||||
|
|
||||||
**NOTE**: Rollback for data exports is **NOT RECOMMENDED** as it would delete exported files from OCI buckets. Only use rollback if export failed and needs to be restarted.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Expected Changes
|
|
||||||
|
|
||||||
### Data Export Summary
|
|
||||||
**6 CSDB tables exported from OU_CSDB schema:**
|
|
||||||
|
|
||||||
**Group 1: Split DATA + HIST (Time Critical)**
|
|
||||||
1. **DEBT** - Last 6 months → DATA, Older → HIST
|
|
||||||
2. **DEBT_DAILY** - Last 6 months → DATA, Older → HIST
|
|
||||||
|
|
||||||
**Group 2: HIST Only (Weekend Bulk)**
|
|
||||||
3. **INSTR_RAT_FULL** - All data → HIST
|
|
||||||
4. **INSTR_DESC_FULL** - All data → HIST
|
|
||||||
5. **ISSUER_RAT_FULL** - All data → HIST
|
|
||||||
6. **ISSUER_DESC_FULL** - All data → HIST
|
|
||||||
|
|
||||||
### Bucket Destinations (DEV environment)
|
|
||||||
- **DATA Bucket**: `mrds_data_dev/ODS/CSDB/` (CSV format)
|
|
||||||
- **HIST Bucket**: `mrds_hist_dev/ARCHIVE/CSDB/` (Parquet with partitioning)
|
|
||||||
|
|
||||||
### Column Mappings
|
|
||||||
- **All tables**: `A_ETL_LOAD_SET_FK` renamed to `A_WORKFLOW_HISTORY_KEY`
|
|
||||||
- **DEBT**: Removed columns: `IDIRDEPOSITORY`, `VA_BONDDURATION`
|
|
||||||
- **DEBT_DAILY**: Removed columns: `STEPID`, `PROGRAMNAME`, `PROGRAMCEILING`, `PROGRAMSTATUS`, `ISSUERNACE21SECTOR`, `INSTRUMENTQUOTATIONBASIS`
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
### Post-Export Verification
|
|
||||||
|
|
||||||
1. **Verify CSV files in DATA bucket** (DEBT, DEBT_DAILY - last 6 months):
|
|
||||||
```sql
|
|
||||||
-- Check exported files
|
|
||||||
SELECT object_name, bytes
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => 'DEF_CRED_ARN',
|
|
||||||
location_uri => 'https://objectstorage.region.oraclecloud.com/n/namespace/b/mrds_data_dev/o/ODS/CSDB/'
|
|
||||||
)) WHERE object_name LIKE '%CSDB_DEBT%';
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Verify Parquet files in HIST bucket** (all 6 tables):
|
|
||||||
```sql
|
|
||||||
-- Check archived files with Hive partitioning
|
|
||||||
SELECT object_name, bytes
|
|
||||||
FROM TABLE(DBMS_CLOUD.LIST_OBJECTS(
|
|
||||||
credential_name => 'DEF_CRED_ARN',
|
|
||||||
location_uri => 'https://objectstorage.region.oraclecloud.com/n/namespace/b/mrds_hist_dev/o/ARCHIVE/CSDB/'
|
|
||||||
)) WHERE object_name LIKE '%PARTITION_YEAR=%';
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Validate row counts match source tables**:
|
|
||||||
```sql
|
|
||||||
-- Compare counts between source and exported data
|
|
||||||
SELECT COUNT(*) FROM OU_CSDB.DEBT;
|
|
||||||
SELECT COUNT(*) FROM ODS.CSDB_DEBT_ODS; -- External table pointing to DATA
|
|
||||||
SELECT COUNT(*) FROM ODS.CSDB_DEBT_ARCHIVE; -- External table pointing to HIST
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Verify column mappings**:
|
|
||||||
```sql
|
|
||||||
-- Check A_WORKFLOW_HISTORY_KEY exists in exported data
|
|
||||||
SELECT A_WORKFLOW_HISTORY_KEY, COUNT(*)
|
|
||||||
FROM ODS.CSDB_DEBT_ARCHIVE
|
|
||||||
GROUP BY A_WORKFLOW_HISTORY_KEY;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Known Issues
|
|
||||||
|
|
||||||
### Timing Constraints
|
|
||||||
- **DATA exports (DEBT, DEBT_DAILY)**: Must execute during parallel old+new loads phase after Production deployment
|
|
||||||
- **HIST exports (all 6 tables)**: Can run anytime, recommended for weekend bulk execution to avoid interference
|
|
||||||
|
|
||||||
### Environment-Specific Configuration
|
|
||||||
- Bucket names must be adjusted for each environment:
|
|
||||||
- DEV: `mrds_data_dev`, `mrds_hist_dev`
|
|
||||||
- TEST: `mrds_data_test`, `mrds_hist_test`
|
|
||||||
- PROD: `mrds_data_prod`, `mrds_hist_prod`
|
|
||||||
|
|
||||||
### Data Cutoff Date
|
|
||||||
- Export scripts use 6-month cutoff date calculated as `ADD_MONTHS(SYSDATE, -6)`
|
|
||||||
- Verify cutoff aligns with business requirements before execution
|
|
||||||
|
|
||||||
### One-Time Execution
|
|
||||||
- This is a **ONE-TIME data migration** package
|
|
||||||
- After successful execution, package should be **deactivated** (moved to REL01_POST_DEACTIVATION)
|
|
||||||
- Do not re-run unless explicitly required for data refresh
|
|
||||||
|
|
||||||
## Related
|
|
||||||
- **JIRA**: MARS-835 - CSDB Data Export to External Tables
|
|
||||||
- **Confluence**: FILE_MANAGER package - MRDS - Technical Team
|
|
||||||
- **Confluence**: Table Setup Guide for FILE PROCESSOR System
|
|
||||||
- **Source Schema**: OU_CSDB (Operational Database)
|
|
||||||
- **Target Schema**: ODS (External Tables)
|
|
||||||
- **Migration Type**: One-time bulk export (deactivated post-execution)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Author:** Grzegorz Michalski
|
|
||||||
**Date:** 2025-12-04
|
|
||||||
**Version:** 1.0.0
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
# MARS-835: Required External Tables for Smart Column Mapping
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
This document lists all external tables required for MARS-835 data exports using DATA_EXPORTER v2.4.0 with Smart Column Mapping feature.
|
|
||||||
|
|
||||||
**Purpose**: Smart Column Mapping ensures CSV files are generated with columns in the EXACT order expected by external tables, preventing NULL values due to Oracle's positional CSV mapping.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Required External Tables
|
|
||||||
|
|
||||||
### Group 1: DATA Bucket (CSV Format) - **CRITICAL**
|
|
||||||
|
|
||||||
#### 1. ODS.CSDB_DEBT_DATA_ODS
|
|
||||||
- **Source Table**: OU_CSDB.LEGACY_DEBT
|
|
||||||
- **Format**: CSV
|
|
||||||
- **Bucket**: DATA (mrds_data_dev/ODS/CSDB/CSDB_DEBT/)
|
|
||||||
- **Key Column Mapping**: A_ETL_LOAD_SET_FK → A_WORKFLOW_HISTORY_KEY (position 2 recommended)
|
|
||||||
- **Critical**: Must use Smart Column Mapping to avoid NULL values in A_WORKFLOW_HISTORY_KEY
|
|
||||||
|
|
||||||
#### 2. ODS.CSDB_DEBT_DAILY_DATA_ODS
|
|
||||||
- **Source Table**: OU_CSDB.LEGACY_DEBT_DAILY
|
|
||||||
- **Format**: CSV
|
|
||||||
- **Bucket**: DATA (mrds_data_dev/ODS/CSDB/CSDB_DEBT_DAILY/)
|
|
||||||
- **Key Column Mapping**: A_ETL_LOAD_SET_FK → A_WORKFLOW_HISTORY_KEY (position 2 recommended)
|
|
||||||
- **Critical**: Must use Smart Column Mapping to avoid NULL values in A_WORKFLOW_HISTORY_KEY
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Group 2: ARCHIVE Bucket (Parquet Format) - **RECOMMENDED**
|
|
||||||
|
|
||||||
#### 3. ODS.CSDB_DEBT_ARCHIVE
|
|
||||||
- **Source Table**: OU_CSDB.LEGACY_DEBT
|
|
||||||
- **Format**: Parquet with Hive partitioning
|
|
||||||
- **Bucket**: ARCHIVE (mrds_hist_dev/ARCHIVE/CSDB/CSDB_DEBT/)
|
|
||||||
- **Key Column Mapping**: A_ETL_LOAD_SET_FK → A_WORKFLOW_HISTORY_KEY
|
|
||||||
- **Note**: Parquet uses schema-based mapping (column order less critical but Smart Column Mapping ensures consistency)
|
|
||||||
|
|
||||||
#### 4. ODS.CSDB_DEBT_DAILY_ARCHIVE
|
|
||||||
- **Source Table**: OU_CSDB.LEGACY_DEBT_DAILY
|
|
||||||
- **Format**: Parquet with Hive partitioning
|
|
||||||
- **Bucket**: ARCHIVE (mrds_hist_dev/ARCHIVE/CSDB/CSDB_DEBT_DAILY/)
|
|
||||||
- **Key Column Mapping**: A_ETL_LOAD_SET_FK → A_WORKFLOW_HISTORY_KEY
|
|
||||||
|
|
||||||
#### 5. ODS.CSDB_INSTR_RAT_FULL_ARCHIVE
|
|
||||||
- **Source Table**: OU_CSDB.LEGACY_INSTR_RAT_FULL
|
|
||||||
- **Format**: Parquet with Hive partitioning
|
|
||||||
- **Bucket**: ARCHIVE (mrds_hist_dev/ARCHIVE/CSDB/CSDB_INSTR_RAT_FULL/)
|
|
||||||
- **Key Column Mapping**: A_ETL_LOAD_SET_FK → A_WORKFLOW_HISTORY_KEY
|
|
||||||
|
|
||||||
#### 6. ODS.CSDB_INSTR_DESC_FULL_ARCHIVE
|
|
||||||
- **Source Table**: OU_CSDB.LEGACY_INSTR_DESC_FULL
|
|
||||||
- **Format**: Parquet with Hive partitioning
|
|
||||||
- **Bucket**: ARCHIVE (mrds_hist_dev/ARCHIVE/CSDB/CSDB_INSTR_DESC_FULL/)
|
|
||||||
- **Key Column Mapping**: A_ETL_LOAD_SET_FK → A_WORKFLOW_HISTORY_KEY
|
|
||||||
|
|
||||||
#### 7. ODS.CSDB_ISSUER_RAT_FULL_ARCHIVE
|
|
||||||
- **Source Table**: OU_CSDB.LEGACY_ISSUER_RAT_FULL
|
|
||||||
- **Format**: Parquet with Hive partitioning
|
|
||||||
- **Bucket**: ARCHIVE (mrds_hist_dev/ARCHIVE/CSDB/CSDB_ISSUER_RAT_FULL/)
|
|
||||||
- **Key Column Mapping**: A_ETL_LOAD_SET_FK → A_WORKFLOW_HISTORY_KEY
|
|
||||||
|
|
||||||
#### 8. ODS.CSDB_ISSUER_DESC_FULL_ARCHIVE
|
|
||||||
- **Source Table**: OU_CSDB.LEGACY_ISSUER_DESC_FULL
|
|
||||||
- **Format**: Parquet with Hive partitioning
|
|
||||||
- **Bucket**: ARCHIVE (mrds_hist_dev/ARCHIVE/CSDB/CSDB_ISSUER_DESC_FULL/)
|
|
||||||
- **Key Column Mapping**: A_ETL_LOAD_SET_FK → A_WORKFLOW_HISTORY_KEY
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## External Table Column Order Requirements
|
|
||||||
|
|
||||||
### **CRITICAL for CSV Tables** (DATA bucket):
|
|
||||||
|
|
||||||
All CSV external tables MUST have **A_WORKFLOW_HISTORY_KEY at position 2**:
|
|
||||||
|
|
||||||
```
|
|
||||||
Position 1: A_KEY (NUMBER)
|
|
||||||
Position 2: A_WORKFLOW_HISTORY_KEY (NUMBER) ← MUST BE HERE!
|
|
||||||
Position 3+: Other columns in any order
|
|
||||||
```
|
|
||||||
|
|
||||||
**Reason**: Oracle External Tables with CSV format use **positional mapping** (ignore header row). If source table has A_ETL_LOAD_SET_FK at position 72, but CSV puts it at position 72 while external table expects A_WORKFLOW_HISTORY_KEY at position 2, the external table will try to read position 2 (which might be a DATE column) as NUMBER → conversion fails → NULL value.
|
|
||||||
|
|
||||||
**Solution**: Smart Column Mapping (v2.4.0) generates CSV columns in EXTERNAL TABLE order, ensuring position 2 has the correct NUMBER value.
|
|
||||||
|
|
||||||
### **OPTIONAL for Parquet Tables** (ARCHIVE bucket):
|
|
||||||
|
|
||||||
Parquet format uses **schema-based mapping** (column names). Column order doesn't matter, but Smart Column Mapping provides consistency.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Creation Script Example
|
|
||||||
|
|
||||||
### CSV External Table (CRITICAL - Correct Column Order)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Example: ODS.CSDB_DEBT_DATA_ODS
|
|
||||||
-- IMPORTANT: A_WORKFLOW_HISTORY_KEY must be at position 2!
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
|
||||||
pTableName => 'CSDB_DEBT_DATA_ODS',
|
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_DEBT_TEMPLATE',
|
|
||||||
pPrefix => 'ODS/CSDB/CSDB_DEBT',
|
|
||||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri,
|
|
||||||
pFormat => 'CSV' -- Uses positional mapping!
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Verify column order (A_WORKFLOW_HISTORY_KEY should be position 2)
|
|
||||||
SELECT column_id, column_name, data_type
|
|
||||||
FROM all_tab_columns
|
|
||||||
WHERE table_name = 'CSDB_DEBT_DATA_ODS'
|
|
||||||
AND owner = 'ODS'
|
|
||||||
ORDER BY column_id;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parquet External Table (Optional Column Order)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Example: ODS.CSDB_DEBT_ARCHIVE
|
|
||||||
-- Column order flexible (schema-based mapping)
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
|
||||||
pTableName => 'CSDB_DEBT_ARCHIVE',
|
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.CSDB_DEBT_TEMPLATE',
|
|
||||||
pPrefix => 'ARCHIVE/CSDB/CSDB_DEBT',
|
|
||||||
pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri,
|
|
||||||
pFormat => 'PARQUET' -- Uses schema-based mapping
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Template Tables Required
|
|
||||||
|
|
||||||
All external tables require corresponding template tables in CT_ET_TEMPLATES schema:
|
|
||||||
|
|
||||||
- `CT_ET_TEMPLATES.CSDB_DEBT_TEMPLATE`
|
|
||||||
- `CT_ET_TEMPLATES.CSDB_DEBT_DAILY_TEMPLATE`
|
|
||||||
- `CT_ET_TEMPLATES.CSDB_INSTR_RAT_FULL_TEMPLATE`
|
|
||||||
- `CT_ET_TEMPLATES.CSDB_INSTR_DESC_FULL_TEMPLATE`
|
|
||||||
- `CT_ET_TEMPLATES.CSDB_ISSUER_RAT_FULL_TEMPLATE`
|
|
||||||
- `CT_ET_TEMPLATES.CSDB_ISSUER_DESC_FULL_TEMPLATE`
|
|
||||||
|
|
||||||
**Note**: Template tables must be created by ADMIN or CT_ET_TEMPLATES user (MRDS_LOADER cannot create them).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Verification Checklist
|
|
||||||
|
|
||||||
Before running MARS-835 exports:
|
|
||||||
|
|
||||||
- [ ] All 8 external tables exist in ODS schema
|
|
||||||
- [ ] CSV tables (DATA bucket) have A_WORKFLOW_HISTORY_KEY at position 2
|
|
||||||
- [ ] Template tables exist in CT_ET_TEMPLATES schema
|
|
||||||
- [ ] MRDS_LOADER has EXECUTE privilege on ODS.FILE_MANAGER_ODS
|
|
||||||
- [ ] ODS schema has access to CT_MRDS.ENV_MANAGER for logging
|
|
||||||
- [ ] DATA_EXPORTER v2.4.0 deployed with Smart Column Mapping feature
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing Verification
|
|
||||||
|
|
||||||
After export, verify A_WORKFLOW_HISTORY_KEY is not NULL:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- CSV tables (should be 100% populated)
|
|
||||||
SELECT 'CSDB_DEBT_DATA_ODS' AS TABLE_NAME,
|
|
||||||
COUNT(*) AS TOTAL_ROWS,
|
|
||||||
COUNT(A_WORKFLOW_HISTORY_KEY) AS NON_NULL_COUNT,
|
|
||||||
ROUND(COUNT(A_WORKFLOW_HISTORY_KEY) * 100.0 / NULLIF(COUNT(*), 0), 2) AS SUCCESS_RATE_PCT
|
|
||||||
FROM ODS.CSDB_DEBT_DATA_ODS;
|
|
||||||
|
|
||||||
SELECT 'CSDB_DEBT_DAILY_DATA_ODS' AS TABLE_NAME,
|
|
||||||
COUNT(*) AS TOTAL_ROWS,
|
|
||||||
COUNT(A_WORKFLOW_HISTORY_KEY) AS NON_NULL_COUNT,
|
|
||||||
ROUND(COUNT(A_WORKFLOW_HISTORY_KEY) * 100.0 / NULLIF(COUNT(*), 0), 2) AS SUCCESS_RATE_PCT
|
|
||||||
FROM ODS.CSDB_DEBT_DAILY_DATA_ODS;
|
|
||||||
|
|
||||||
-- Parquet tables (should also be 100% populated)
|
|
||||||
SELECT 'CSDB_DEBT_ARCHIVE' AS TABLE_NAME,
|
|
||||||
COUNT(*) AS TOTAL_ROWS,
|
|
||||||
COUNT(A_WORKFLOW_HISTORY_KEY) AS NON_NULL_COUNT,
|
|
||||||
ROUND(COUNT(A_WORKFLOW_HISTORY_KEY) * 100.0 / NULLIF(COUNT(*), 0), 2) AS SUCCESS_RATE_PCT
|
|
||||||
FROM ODS.CSDB_DEBT_ARCHIVE;
|
|
||||||
```
|
|
||||||
|
|
||||||
**Expected Result**: SUCCESS_RATE_PCT = 100.00 for all tables
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Related Documentation
|
|
||||||
|
|
||||||
- [DATA_EXPORTER v2.4.0 Smart Column Mapping Examples](../MARS-835-PREHOOK/current_version/v2.3.0/DATA_EXPORTER_v2.4.0_Smart_Column_Mapping_Examples.sql)
|
|
||||||
- [Oracle External Tables Column Order Issue](../../confluence/additions/Oracle_External_Tables_Column_Order_Issue.md)
|
|
||||||
- [MARS-835 README](README.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Last Updated**: 2026-01-09
|
|
||||||
**Author**: GitHub Copilot (MARS-835 Update)
|
|
||||||
@@ -59,7 +59,13 @@ PROMPT =========================================================================
|
|||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 3: Verify Rollback Completed
|
PROMPT Step 3: Delete File Registration Records from A_SOURCE_FILE_RECEIVED
|
||||||
|
PROMPT =========================================================================
|
||||||
|
@@90_MARS_835_rollback_file_registrations.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT =========================================================================
|
||||||
|
PROMPT Step 4: Verify Rollback Completed
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@99_MARS_835_verify_rollback.sql
|
@@99_MARS_835_verify_rollback.sql
|
||||||
|
|
||||||
|
|||||||
5
MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/.gitignore
vendored
Normal file
5
MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Exclude temporary folders from version control
|
||||||
|
confluence/
|
||||||
|
log/
|
||||||
|
test/
|
||||||
|
mock_data/
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409-POSTHOOK Step 01: Update A_WORKFLOW_HISTORY_KEY for existing records
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Populate A_WORKFLOW_HISTORY_KEY for existing A_SOURCE_FILE_RECEIVED records
|
||||||
|
-- by extracting values from corresponding ODS tables
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-03-13
|
||||||
|
-- Prerequisites:
|
||||||
|
-- - MARS-1409 installed (A_WORKFLOW_HISTORY_KEY column exists in A_SOURCE_FILE_RECEIVED)
|
||||||
|
-- - ODS tables contain A_WORKFLOW_HISTORY_KEY and file$name columns
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Updating A_WORKFLOW_HISTORY_KEY for existing A_SOURCE_FILE_RECEIVED records...
|
||||||
|
|
||||||
|
DECLARE
|
||||||
|
vUpdatedTotal NUMBER := 0;
|
||||||
|
vUpdatedCurrent NUMBER := 0;
|
||||||
|
vFailedConfigs NUMBER := 0;
|
||||||
|
vTableNotFound NUMBER := 0;
|
||||||
|
vSkippedConfigs NUMBER := 0;
|
||||||
|
vEmptyTables NUMBER := 0;
|
||||||
|
vHasData NUMBER := 0;
|
||||||
|
vTableName VARCHAR2(200);
|
||||||
|
vSQL VARCHAR2(32767);
|
||||||
|
vRecordsToUpdate NUMBER := 0;
|
||||||
|
vRemainingTargeted NUMBER := 0;
|
||||||
|
vTableExists NUMBER := 0;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
-- Count total records to update
|
||||||
|
SELECT COUNT(*) INTO vRecordsToUpdate
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE A_WORKFLOW_HISTORY_KEY IS NULL
|
||||||
|
AND PROCESSING_STATUS IN ('VALIDATED', 'READY_FOR_INGESTION', 'INGESTED', 'ARCHIVED', 'ARCHIVED_AND_TRASHED', 'ARCHIVED_AND_PURGED');
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Found ' || vRecordsToUpdate || ' records with NULL A_WORKFLOW_HISTORY_KEY');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('----------------------------------------');
|
||||||
|
|
||||||
|
-- Process each INPUT configuration that has records to update
|
||||||
|
FOR config_rec IN (
|
||||||
|
SELECT
|
||||||
|
sfc.A_SOURCE_FILE_CONFIG_KEY,
|
||||||
|
sfc.A_SOURCE_KEY,
|
||||||
|
sfc.SOURCE_FILE_ID,
|
||||||
|
sfc.TABLE_ID,
|
||||||
|
sfc.TEMPLATE_TABLE_NAME,
|
||||||
|
(SELECT COUNT(*)
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr
|
||||||
|
WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = sfc.A_SOURCE_FILE_CONFIG_KEY
|
||||||
|
AND sfr.A_WORKFLOW_HISTORY_KEY IS NULL
|
||||||
|
AND sfr.PROCESSING_STATUS IN ('VALIDATED', 'READY_FOR_INGESTION', 'INGESTED', 'ARCHIVED', 'ARCHIVED_AND_TRASHED', 'ARCHIVED_AND_PURGED')
|
||||||
|
) AS NULL_COUNT
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG sfc
|
||||||
|
WHERE sfc.SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND sfc.TABLE_ID IS NOT NULL
|
||||||
|
ORDER BY sfc.A_SOURCE_KEY, sfc.SOURCE_FILE_ID, sfc.TABLE_ID
|
||||||
|
) LOOP
|
||||||
|
|
||||||
|
IF config_rec.NULL_COUNT = 0 THEN
|
||||||
|
vSkippedConfigs := vSkippedConfigs + 1;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SKIP: Config ' || config_rec.A_SOURCE_FILE_CONFIG_KEY ||
|
||||||
|
' (' || config_rec.A_SOURCE_KEY || '/' || config_rec.SOURCE_FILE_ID || '/' || config_rec.TABLE_ID ||
|
||||||
|
') - no records to update');
|
||||||
|
CONTINUE;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
-- Construct ODS table name from TABLE_ID (ODS tables have _ODS suffix)
|
||||||
|
vTableName := 'ODS.' || config_rec.TABLE_ID || '_ODS';
|
||||||
|
|
||||||
|
-- Check table existence before attempting dynamic SQL
|
||||||
|
SELECT COUNT(*) INTO vTableExists
|
||||||
|
FROM ALL_TABLES
|
||||||
|
WHERE OWNER = 'ODS'
|
||||||
|
AND TABLE_NAME = config_rec.TABLE_ID || '_ODS';
|
||||||
|
|
||||||
|
IF vTableExists = 0 THEN
|
||||||
|
vTableNotFound := vTableNotFound + 1;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SKIP: Config ' || config_rec.A_SOURCE_FILE_CONFIG_KEY ||
|
||||||
|
' (' || config_rec.A_SOURCE_KEY || '/' || config_rec.SOURCE_FILE_ID || '/' || config_rec.TABLE_ID ||
|
||||||
|
') - ODS table not found: ' || vTableName);
|
||||||
|
CONTINUE;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Pre-check: verify ODS table has accessible data (empty external table throws ORA-29913/KUP-05002)
|
||||||
|
vHasData := 0;
|
||||||
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM (SELECT 1 FROM ' || vTableName || ' t WHERE ROWNUM = 1)'
|
||||||
|
INTO vHasData;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF SQLCODE = -29913 OR INSTR(SQLERRM, 'KUP-05002') > 0 THEN
|
||||||
|
NULL; -- vHasData stays 0
|
||||||
|
ELSE
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
|
||||||
|
IF vHasData = 0 THEN
|
||||||
|
vEmptyTables := vEmptyTables + 1;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SKIP: Config ' || config_rec.A_SOURCE_FILE_CONFIG_KEY ||
|
||||||
|
' (' || config_rec.A_SOURCE_KEY || '/' || config_rec.SOURCE_FILE_ID || '/' || config_rec.TABLE_ID ||
|
||||||
|
') - ODS table has no files at storage location (empty): ' || vTableName);
|
||||||
|
CONTINUE;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Processing config ' || config_rec.A_SOURCE_FILE_CONFIG_KEY ||
|
||||||
|
' (' || config_rec.A_SOURCE_KEY || '/' || config_rec.SOURCE_FILE_ID || '/' || config_rec.TABLE_ID || ')...');
|
||||||
|
|
||||||
|
-- Update using ODS table
|
||||||
|
-- NO_PARALLEL hint required: ODS external tables (OCI Object Storage) fail with ORA-12801 under parallel query
|
||||||
|
vSQL :=
|
||||||
|
'UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
'SET A_WORKFLOW_HISTORY_KEY = ( ' ||
|
||||||
|
' SELECT /*+ NO_PARALLEL(t) */ t.A_WORKFLOW_HISTORY_KEY ' ||
|
||||||
|
' FROM ' || vTableName || ' t ' ||
|
||||||
|
' WHERE t.file$name = sfr.SOURCE_FILE_NAME ' ||
|
||||||
|
' AND rownum=1 ' ||
|
||||||
|
') ' ||
|
||||||
|
'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :config_key ' ||
|
||||||
|
' AND sfr.A_WORKFLOW_HISTORY_KEY IS NULL ' ||
|
||||||
|
' AND sfr.PROCESSING_STATUS IN (''VALIDATED'', ''READY_FOR_INGESTION'', ''INGESTED'', ''ARCHIVED'', ''ARCHIVED_AND_TRASHED'', ''ARCHIVED_AND_PURGED'') ' ||
|
||||||
|
' AND EXISTS ( ' ||
|
||||||
|
' SELECT /*+ NO_PARALLEL(t) */ 1 FROM ' || vTableName || ' t ' ||
|
||||||
|
' WHERE t.file$name = sfr.SOURCE_FILE_NAME ' ||
|
||||||
|
' AND rownum=1 ' ||
|
||||||
|
' )';
|
||||||
|
|
||||||
|
EXECUTE IMMEDIATE vSQL USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
commit;
|
||||||
|
vUpdatedCurrent := SQL%ROWCOUNT;
|
||||||
|
vUpdatedTotal := vUpdatedTotal + vUpdatedCurrent;
|
||||||
|
|
||||||
|
IF vUpdatedCurrent > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' SUCCESS: Updated ' || vUpdatedCurrent || ' record(s)');
|
||||||
|
ELSE
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' INFO: No matching records found in ODS table (files may not be ingested yet)');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
vFailedConfigs := vFailedConfigs + 1;
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' ERROR: Unexpected failure for config ' || config_rec.A_SOURCE_FILE_CONFIG_KEY ||
|
||||||
|
' (table: ' || vTableName || ')');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Reason: ' || SQLERRM);
|
||||||
|
-- Continue processing other configurations despite this failure
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('----------------------------------------');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Update Summary:');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Total records updated: ' || vUpdatedTotal);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Configurations skipped (no NULL records): ' || vSkippedConfigs);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Configurations skipped (ODS table not found): ' || vTableNotFound);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Configurations skipped (ODS table empty - no files at location): ' || vEmptyTables);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Configurations failed (unexpected errors): ' || vFailedConfigs);
|
||||||
|
|
||||||
|
-- Check remaining NULL records - targeted statuses only
|
||||||
|
SELECT COUNT(*) INTO vRemainingTargeted
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE A_WORKFLOW_HISTORY_KEY IS NULL
|
||||||
|
AND PROCESSING_STATUS IN ('VALIDATED', 'READY_FOR_INGESTION', 'INGESTED', 'ARCHIVED', 'ARCHIVED_AND_TRASHED', 'ARCHIVED_AND_PURGED');
|
||||||
|
|
||||||
|
-- Check all remaining NULL records (includes RECEIVED, VALIDATION_FAILED)
|
||||||
|
SELECT COUNT(*) INTO vRecordsToUpdate
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE A_WORKFLOW_HISTORY_KEY IS NULL;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Remaining NULL records (targeted statuses): ' || vRemainingTargeted);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Remaining NULL records (all statuses): ' || vRecordsToUpdate);
|
||||||
|
|
||||||
|
IF vRemainingTargeted > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('NOTE: Some records with targeted statuses still have NULL A_WORKFLOW_HISTORY_KEY.');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' This is expected for files not yet ingested into ODS tables');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' or ODS tables with a different structure.');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' These records will be populated when files are re-processed.');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vFailedConfigs > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('NOTE: ' || vFailedConfigs || ' configuration(s) failed with unexpected errors.');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Review the ERROR lines above and investigate manually.');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('----------------------------------------');
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
ROLLBACK;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('FATAL ERROR: ' || SQLERRM);
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Transaction rolled back');
|
||||||
|
RAISE;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Existing workflow keys update completed!
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Step 2: Set PROCESSING_STATUS = 'INGESTED' for records whose workflow
|
||||||
|
-- completed successfully (mirrors trigger A_WORKFLOW_HISTORY logic)
|
||||||
|
-- ============================================================================
|
||||||
|
PROMPT
|
||||||
|
PROMPT Updating PROCESSING_STATUS to INGESTED for completed workflows...
|
||||||
|
|
||||||
|
DECLARE
|
||||||
|
vUpdatedIngested NUMBER := 0;
|
||||||
|
BEGIN
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED sfr
|
||||||
|
SET sfr.PROCESSING_STATUS = 'INGESTED',
|
||||||
|
sfr.PROCESS_NAME = (
|
||||||
|
SELECT wh.service_name
|
||||||
|
FROM CT_MRDS.A_WORKFLOW_HISTORY wh
|
||||||
|
WHERE wh.a_workflow_history_key = sfr.a_workflow_history_key
|
||||||
|
)
|
||||||
|
WHERE sfr.A_WORKFLOW_HISTORY_KEY IS NOT NULL
|
||||||
|
AND sfr.PROCESSING_STATUS IN ('READY_FOR_INGESTION')
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM CT_MRDS.A_WORKFLOW_HISTORY wh
|
||||||
|
WHERE wh.a_workflow_history_key = sfr.a_workflow_history_key
|
||||||
|
AND wh.workflow_successful = 'Y'
|
||||||
|
);
|
||||||
|
|
||||||
|
vUpdatedIngested := SQL%ROWCOUNT;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Updated PROCESSING_STATUS to INGESTED: ' || vUpdatedIngested || ' record(s)');
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
ROLLBACK;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('FATAL ERROR: ' || SQLERRM);
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Transaction rolled back');
|
||||||
|
RAISE;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT INGESTED status update completed!
|
||||||
|
PROMPT
|
||||||
@@ -0,0 +1,373 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Diagnostic: Workflow key status after step 09
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: For each INPUT config with an ODS table, report:
|
||||||
|
-- [A] Files present in ODS bucket but NOT registered in A_SOURCE_FILE_RECEIVED
|
||||||
|
-- [B] Files registered in A_SOURCE_FILE_RECEIVED but NOT in ODS bucket
|
||||||
|
-- [C] Files present in both - with A_WORKFLOW_HISTORY_KEY populated
|
||||||
|
-- [D] Files present in both - A_WORKFLOW_HISTORY_KEY still NULL
|
||||||
|
--
|
||||||
|
-- Can be run at any time, read-only (no DML).
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
SET LINESIZE 200
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Diagnosing workflow key status (ODS bucket vs A_SOURCE_FILE_RECEIVED)
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
DECLARE
|
||||||
|
TYPE tStringList IS TABLE OF VARCHAR2(500);
|
||||||
|
|
||||||
|
vTableName VARCHAR2(200);
|
||||||
|
vTableExists NUMBER;
|
||||||
|
vBucketEmpty BOOLEAN;
|
||||||
|
vRefCursor SYS_REFCURSOR;
|
||||||
|
vFileName VARCHAR2(500);
|
||||||
|
|
||||||
|
-- Per-config counters
|
||||||
|
vOnlyInBucket NUMBER;
|
||||||
|
vOnlyInDB NUMBER;
|
||||||
|
vInBothWithKey NUMBER;
|
||||||
|
vInBothNoKey NUMBER;
|
||||||
|
|
||||||
|
-- Grand totals
|
||||||
|
vConfigsChecked NUMBER := 0;
|
||||||
|
vConfigsWithIssues NUMBER := 0;
|
||||||
|
vTotalOnlyInBucket NUMBER := 0;
|
||||||
|
vTotalOnlyInDB NUMBER := 0;
|
||||||
|
vTotalInBothWithKey NUMBER := 0;
|
||||||
|
vTotalInBothNoKey NUMBER := 0;
|
||||||
|
|
||||||
|
-- How many individual file names to print per category before summarising
|
||||||
|
cMaxPrint CONSTANT NUMBER := 1000;
|
||||||
|
vPrinted NUMBER;
|
||||||
|
|
||||||
|
FUNCTION IS_EXTERNAL_TABLE_EMPTY_ERROR(
|
||||||
|
pSqlCode NUMBER,
|
||||||
|
pSqlErrm VARCHAR2
|
||||||
|
) RETURN BOOLEAN
|
||||||
|
IS
|
||||||
|
BEGIN
|
||||||
|
RETURN pSqlCode IN (-29913, -29400)
|
||||||
|
OR INSTR(pSqlErrm, 'KUP-05002') > 0;
|
||||||
|
END;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
FOR config_rec IN (
|
||||||
|
SELECT sfc.A_SOURCE_FILE_CONFIG_KEY,
|
||||||
|
sfc.A_SOURCE_KEY,
|
||||||
|
sfc.SOURCE_FILE_ID,
|
||||||
|
sfc.TABLE_ID
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG sfc
|
||||||
|
WHERE sfc.SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND sfc.TABLE_ID IS NOT NULL
|
||||||
|
ORDER BY sfc.A_SOURCE_KEY, sfc.SOURCE_FILE_ID, sfc.TABLE_ID
|
||||||
|
) LOOP
|
||||||
|
|
||||||
|
vTableName := 'ODS.' || config_rec.TABLE_ID || '_ODS';
|
||||||
|
|
||||||
|
SELECT COUNT(*) INTO vTableExists
|
||||||
|
FROM ALL_TABLES
|
||||||
|
WHERE OWNER = 'ODS'
|
||||||
|
AND TABLE_NAME = config_rec.TABLE_ID || '_ODS';
|
||||||
|
|
||||||
|
IF vTableExists = 0 THEN
|
||||||
|
CONTINUE;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Check if the bucket location has any files at all
|
||||||
|
-- (empty bucket raises ORA-29913 instead of returning 0 rows)
|
||||||
|
vBucketEmpty := FALSE;
|
||||||
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE
|
||||||
|
'SELECT COUNT(*) FROM ' || vTableName || ' t WHERE ROWNUM = 1'
|
||||||
|
INTO vTableExists;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF IS_EXTERNAL_TABLE_EMPTY_ERROR(SQLCODE, SQLERRM) THEN
|
||||||
|
vBucketEmpty := TRUE;
|
||||||
|
ELSE
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
|
||||||
|
IF vBucketEmpty THEN
|
||||||
|
-- Bucket is empty: nothing in ODS, but registered records are all "not in bucket"
|
||||||
|
vOnlyInBucket := 0;
|
||||||
|
SELECT COUNT(*) INTO vOnlyInDB
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr
|
||||||
|
WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = config_rec.A_SOURCE_FILE_CONFIG_KEY
|
||||||
|
AND sfr.PROCESSING_STATUS IN ('VALIDATED','READY_FOR_INGESTION','INGESTED','ARCHIVED','ARCHIVED_AND_TRASHED','ARCHIVED_AND_PURGED');
|
||||||
|
vInBothWithKey := 0;
|
||||||
|
vInBothNoKey := 0;
|
||||||
|
ELSE
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
-- [A] In ODS bucket but NOT in A_SOURCE_FILE_RECEIVED
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
EXECUTE IMMEDIATE
|
||||||
|
'SELECT COUNT(DISTINCT t.file$name) ' ||
|
||||||
|
'FROM ' || vTableName || ' t ' ||
|
||||||
|
'WHERE t.file$name IS NOT NULL ' ||
|
||||||
|
' AND NOT EXISTS ( ' ||
|
||||||
|
' SELECT 1 FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
' WHERE sfr.SOURCE_FILE_NAME = t.file$name ' ||
|
||||||
|
' AND sfr.A_SOURCE_FILE_CONFIG_KEY = :1)'
|
||||||
|
INTO vOnlyInBucket
|
||||||
|
USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
-- [B] In A_SOURCE_FILE_RECEIVED (targeted statuses) but NOT in ODS bucket
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
EXECUTE IMMEDIATE
|
||||||
|
'SELECT COUNT(*) ' ||
|
||||||
|
'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' ||
|
||||||
|
' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' ||
|
||||||
|
' AND NOT EXISTS ( ' ||
|
||||||
|
' SELECT 1 FROM ' || vTableName || ' t ' ||
|
||||||
|
' WHERE t.file$name = sfr.SOURCE_FILE_NAME)'
|
||||||
|
INTO vOnlyInDB
|
||||||
|
USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
-- [C] In both, A_WORKFLOW_HISTORY_KEY IS NOT NULL
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
EXECUTE IMMEDIATE
|
||||||
|
'SELECT COUNT(DISTINCT sfr.A_SOURCE_FILE_RECEIVED_KEY) ' ||
|
||||||
|
'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' ||
|
||||||
|
' AND sfr.A_WORKFLOW_HISTORY_KEY IS NOT NULL ' ||
|
||||||
|
' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' ||
|
||||||
|
' AND EXISTS ( ' ||
|
||||||
|
' SELECT 1 FROM ' || vTableName || ' t ' ||
|
||||||
|
' WHERE t.file$name = sfr.SOURCE_FILE_NAME)'
|
||||||
|
INTO vInBothWithKey
|
||||||
|
USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
-- [D] In both, A_WORKFLOW_HISTORY_KEY IS NULL
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
EXECUTE IMMEDIATE
|
||||||
|
'SELECT COUNT(DISTINCT sfr.A_SOURCE_FILE_RECEIVED_KEY) ' ||
|
||||||
|
'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' ||
|
||||||
|
' AND sfr.A_WORKFLOW_HISTORY_KEY IS NULL ' ||
|
||||||
|
' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' ||
|
||||||
|
' AND EXISTS ( ' ||
|
||||||
|
' SELECT 1 FROM ' || vTableName || ' t ' ||
|
||||||
|
' WHERE t.file$name = sfr.SOURCE_FILE_NAME)'
|
||||||
|
INTO vInBothNoKey
|
||||||
|
USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF IS_EXTERNAL_TABLE_EMPTY_ERROR(SQLCODE, SQLERRM) THEN
|
||||||
|
vBucketEmpty := TRUE;
|
||||||
|
vOnlyInBucket := 0;
|
||||||
|
SELECT COUNT(*) INTO vOnlyInDB
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr
|
||||||
|
WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = config_rec.A_SOURCE_FILE_CONFIG_KEY
|
||||||
|
AND sfr.PROCESSING_STATUS IN ('VALIDATED','READY_FOR_INGESTION','INGESTED','ARCHIVED','ARCHIVED_AND_TRASHED','ARCHIVED_AND_PURGED');
|
||||||
|
vInBothWithKey := 0;
|
||||||
|
vInBothNoKey := 0;
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' NOTE: ODS bucket became empty/inaccessible during diagnostics for ' || vTableName || '. Falling back to DB-only counts for [B].');
|
||||||
|
ELSE
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
|
||||||
|
END IF; -- vBucketEmpty
|
||||||
|
|
||||||
|
-- Skip configs with nothing to report
|
||||||
|
IF vOnlyInBucket = 0 AND vOnlyInDB = 0 AND vInBothWithKey = 0 AND vInBothNoKey = 0 THEN
|
||||||
|
CONTINUE;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
vConfigsChecked := vConfigsChecked + 1;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Config ' || config_rec.A_SOURCE_FILE_CONFIG_KEY ||
|
||||||
|
' (' || config_rec.A_SOURCE_KEY ||
|
||||||
|
'/' || config_rec.SOURCE_FILE_ID ||
|
||||||
|
'/' || config_rec.TABLE_ID || ')');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [A] In bucket, not registered: ' || vOnlyInBucket);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [B] Registered, not in bucket: ' || vOnlyInDB);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [C] In both, A_WORKFLOW_HISTORY_KEY set: ' || vInBothWithKey);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [D] In both, A_WORKFLOW_HISTORY_KEY NULL: ' || vInBothNoKey);
|
||||||
|
|
||||||
|
-- Print individual file names for categories with problems
|
||||||
|
IF vOnlyInBucket > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [A] Files in bucket not registered:');
|
||||||
|
vPrinted := 0;
|
||||||
|
OPEN vRefCursor FOR
|
||||||
|
'SELECT DISTINCT t.file$name ' ||
|
||||||
|
'FROM ' || vTableName || ' t ' ||
|
||||||
|
'WHERE t.file$name IS NOT NULL ' ||
|
||||||
|
' AND NOT EXISTS ( ' ||
|
||||||
|
' SELECT 1 FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
' WHERE sfr.SOURCE_FILE_NAME = t.file$name ' ||
|
||||||
|
' AND sfr.A_SOURCE_FILE_CONFIG_KEY = :1) ' ||
|
||||||
|
'ORDER BY t.file$name'
|
||||||
|
USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
LOOP
|
||||||
|
FETCH vRefCursor INTO vFileName;
|
||||||
|
EXIT WHEN vRefCursor%NOTFOUND;
|
||||||
|
vPrinted := vPrinted + 1;
|
||||||
|
IF vPrinted <= cMaxPrint THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' ' || vFileName);
|
||||||
|
ELSIF vPrinted = cMaxPrint + 1 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' ... and ' || (vOnlyInBucket - cMaxPrint) || ' more');
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vRefCursor;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vOnlyInDB > 0 THEN
|
||||||
|
vConfigsWithIssues := vConfigsWithIssues + 1;
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [B] Registered files not found in bucket:');
|
||||||
|
vPrinted := 0;
|
||||||
|
BEGIN
|
||||||
|
IF vBucketEmpty THEN
|
||||||
|
OPEN vRefCursor FOR
|
||||||
|
'SELECT sfr.SOURCE_FILE_NAME, sfr.PROCESSING_STATUS, sfr.A_WORKFLOW_HISTORY_KEY ' ||
|
||||||
|
'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' ||
|
||||||
|
' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' ||
|
||||||
|
'ORDER BY sfr.SOURCE_FILE_NAME'
|
||||||
|
USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
ELSE
|
||||||
|
OPEN vRefCursor FOR
|
||||||
|
'SELECT sfr.SOURCE_FILE_NAME, sfr.PROCESSING_STATUS, sfr.A_WORKFLOW_HISTORY_KEY ' ||
|
||||||
|
'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' ||
|
||||||
|
' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' ||
|
||||||
|
' AND NOT EXISTS ( ' ||
|
||||||
|
' SELECT 1 FROM ' || vTableName || ' t ' ||
|
||||||
|
' WHERE t.file$name = sfr.SOURCE_FILE_NAME) ' ||
|
||||||
|
'ORDER BY sfr.SOURCE_FILE_NAME'
|
||||||
|
USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
END IF;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF IS_EXTERNAL_TABLE_EMPTY_ERROR(SQLCODE, SQLERRM) THEN
|
||||||
|
vBucketEmpty := TRUE;
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' NOTE: Skipping ODS anti-join details due to empty/inaccessible external table for ' || vTableName || '.');
|
||||||
|
OPEN vRefCursor FOR
|
||||||
|
'SELECT sfr.SOURCE_FILE_NAME, sfr.PROCESSING_STATUS, sfr.A_WORKFLOW_HISTORY_KEY ' ||
|
||||||
|
'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' ||
|
||||||
|
' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' ||
|
||||||
|
'ORDER BY sfr.SOURCE_FILE_NAME'
|
||||||
|
USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
ELSE
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
LOOP
|
||||||
|
DECLARE
|
||||||
|
vStatus VARCHAR2(50);
|
||||||
|
vWfKey NUMBER;
|
||||||
|
BEGIN
|
||||||
|
FETCH vRefCursor INTO vFileName, vStatus, vWfKey;
|
||||||
|
EXIT WHEN vRefCursor%NOTFOUND;
|
||||||
|
vPrinted := vPrinted + 1;
|
||||||
|
IF vPrinted <= cMaxPrint THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' ' || vFileName ||
|
||||||
|
' status=' || vStatus ||
|
||||||
|
' wf_key=' || NVL(TO_CHAR(vWfKey), 'NULL'));
|
||||||
|
ELSIF vPrinted = cMaxPrint + 1 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' ... and ' || (vOnlyInDB - cMaxPrint) || ' more');
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vRefCursor;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vInBothNoKey > 0 THEN
|
||||||
|
vConfigsWithIssues := vConfigsWithIssues + 1;
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [D] Files in both but A_WORKFLOW_HISTORY_KEY still NULL:');
|
||||||
|
vPrinted := 0;
|
||||||
|
OPEN vRefCursor FOR
|
||||||
|
'SELECT sfr.SOURCE_FILE_NAME, sfr.PROCESSING_STATUS ' ||
|
||||||
|
'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' ||
|
||||||
|
'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' ||
|
||||||
|
' AND sfr.A_WORKFLOW_HISTORY_KEY IS NULL ' ||
|
||||||
|
' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' ||
|
||||||
|
' AND EXISTS ( ' ||
|
||||||
|
' SELECT 1 FROM ' || vTableName || ' t ' ||
|
||||||
|
' WHERE t.file$name = sfr.SOURCE_FILE_NAME) ' ||
|
||||||
|
'ORDER BY sfr.SOURCE_FILE_NAME'
|
||||||
|
USING config_rec.A_SOURCE_FILE_CONFIG_KEY;
|
||||||
|
LOOP
|
||||||
|
DECLARE
|
||||||
|
vStatus VARCHAR2(50);
|
||||||
|
BEGIN
|
||||||
|
FETCH vRefCursor INTO vFileName, vStatus;
|
||||||
|
EXIT WHEN vRefCursor%NOTFOUND;
|
||||||
|
vPrinted := vPrinted + 1;
|
||||||
|
IF vPrinted <= cMaxPrint THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' ' || vFileName || ' status=' || vStatus);
|
||||||
|
ELSIF vPrinted = cMaxPrint + 1 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' ... and ' || (vInBothNoKey - cMaxPrint) || ' more');
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vRefCursor;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
|
||||||
|
-- Accumulate totals
|
||||||
|
vTotalOnlyInBucket := vTotalOnlyInBucket + vOnlyInBucket;
|
||||||
|
vTotalOnlyInDB := vTotalOnlyInDB + vOnlyInDB;
|
||||||
|
vTotalInBothWithKey := vTotalInBothWithKey + vInBothWithKey;
|
||||||
|
vTotalInBothNoKey := vTotalInBothNoKey + vInBothNoKey;
|
||||||
|
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('============================================================================');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Grand Summary:');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Configs with data checked: ' || vConfigsChecked);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Configs with issues (B or D): ' || vConfigsWithIssues);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [A] Files in bucket, not registered: ' || vTotalOnlyInBucket);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [B] Registered, not in bucket: ' || vTotalOnlyInDB);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [C] In both - A_WORKFLOW_HISTORY_KEY set: ' || vTotalInBothWithKey);
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' [D] In both - A_WORKFLOW_HISTORY_KEY NULL: ' || vTotalInBothNoKey);
|
||||||
|
DBMS_OUTPUT.PUT_LINE('============================================================================');
|
||||||
|
|
||||||
|
IF vTotalOnlyInDB > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('WARNING [B]: ' || vTotalOnlyInDB || ' registered file(s) not found in ODS bucket.');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' These may have been moved to ARCHIVE or deleted from ODS.');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vTotalInBothNoKey > 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('WARNING [D]: ' || vTotalInBothNoKey || ' file(s) present in both but A_WORKFLOW_HISTORY_KEY is still NULL.');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' ODS table rows for these files may have A_WORKFLOW_HISTORY_KEY = NULL.');
|
||||||
|
DBMS_OUTPUT.PUT_LINE(' Re-run step 09 after the ODS rows are populated by the pipeline.');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vConfigsWithIssues = 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('OK: No issues found. All registered files in ODS have A_WORKFLOW_HISTORY_KEY assigned.');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF vRefCursor%ISOPEN THEN
|
||||||
|
CLOSE vRefCursor;
|
||||||
|
END IF;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('ERROR: ' || SQLERRM);
|
||||||
|
RAISE;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Diagnosis complete.
|
||||||
|
PROMPT
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409-POSTHOOK Rollback Step 91: Clear backfilled A_WORKFLOW_HISTORY_KEY values
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Reset A_WORKFLOW_HISTORY_KEY to NULL for all records in
|
||||||
|
-- A_SOURCE_FILE_RECEIVED. Reverts the backfill performed by
|
||||||
|
-- 01_MARS_1409_POSTHOOK_update_existing_workflow_keys.sql.
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-03-13
|
||||||
|
-- Note: Records populated by the new trigger (after MARS-1409 install) will also
|
||||||
|
-- be cleared. The trigger will repopulate them on next file processing.
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Clearing backfilled A_WORKFLOW_HISTORY_KEY values...
|
||||||
|
|
||||||
|
DECLARE
|
||||||
|
vCleared NUMBER := 0;
|
||||||
|
BEGIN
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
SET A_WORKFLOW_HISTORY_KEY = NULL
|
||||||
|
WHERE A_WORKFLOW_HISTORY_KEY IS NOT NULL;
|
||||||
|
|
||||||
|
vCleared := SQL%ROWCOUNT;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Cleared A_WORKFLOW_HISTORY_KEY for ' || vCleared || ' record(s)');
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Rollback of backfill completed successfully');
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
ROLLBACK;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('FATAL ERROR: ' || SQLERRM);
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Transaction rolled back');
|
||||||
|
RAISE;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Workflow keys rollback completed!
|
||||||
|
PROMPT
|
||||||
60
MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/README.md
Normal file
60
MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/README.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# MARS-1409-POSTHOOK: Backfill A_WORKFLOW_HISTORY_KEY for existing records
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Post-hook for MARS-1409. Backfills `A_WORKFLOW_HISTORY_KEY` in
|
||||||
|
`CT_MRDS.A_SOURCE_FILE_RECEIVED` for historical records that existed before
|
||||||
|
MARS-1409 was installed.
|
||||||
|
|
||||||
|
Matches records by `SOURCE_FILE_NAME` against `file$name` in the corresponding
|
||||||
|
ODS table (`ODS.<TABLE_ID>_ODS`) for each `INPUT` source configuration.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `install_mars1409_posthook.sql` | Master installation script (SPOOL, ACCEPT, quit) |
|
||||||
|
| `rollback_mars1409_posthook.sql` | Master rollback script (SPOOL, ACCEPT, quit) |
|
||||||
|
| `01_MARS_1409_POSTHOOK_update_existing_workflow_keys.sql` | Backfill UPDATE script |
|
||||||
|
| `91_MARS_1409_POSTHOOK_rollback_workflow_keys.sql` | Clear backfilled values |
|
||||||
|
| `track_package_versions.sql` | Universal version tracking (no packages changed) |
|
||||||
|
| `verify_packages_version.sql` | Universal package verification |
|
||||||
|
| `README.md` | This file |
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- MARS-1409 installed (`A_WORKFLOW_HISTORY_KEY` column must exist in `CT_MRDS.A_SOURCE_FILE_RECEIVED`)
|
||||||
|
- ODS tables populated with ingested data
|
||||||
|
- ADMIN user with access to CT_MRDS and ODS schemas
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Execute as ADMIN user
|
||||||
|
Get-Content "MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/install_mars1409_posthook.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
|
||||||
|
```
|
||||||
|
|
||||||
|
Log file created automatically: `log/INSTALL_MARS_1409_POSTHOOK_<PDB>_<timestamp>.log`
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
- Iterates all `INPUT` source configurations from `CT_MRDS.A_SOURCE_FILE_CONFIG`
|
||||||
|
- For each config, joins `A_SOURCE_FILE_RECEIVED` with `ODS.<TABLE_ID>_ODS` on `SOURCE_FILE_NAME = file$name`
|
||||||
|
- Updates `A_WORKFLOW_HISTORY_KEY` for records with statuses:
|
||||||
|
`VALIDATED`, `READY_FOR_INGESTION`, `INGESTED`, `ARCHIVED`, `ARCHIVED_AND_TRASHED`, `ARCHIVED_AND_PURGED`
|
||||||
|
- Skips configs with no NULL records or missing ODS tables
|
||||||
|
- Prints summary with counts per config and overall totals
|
||||||
|
|
||||||
|
## Rollback
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Execute as ADMIN user
|
||||||
|
Get-Content "MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/rollback_mars1409_posthook.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
|
||||||
|
```
|
||||||
|
|
||||||
|
Rollback clears all non-NULL `A_WORKFLOW_HISTORY_KEY` values from `A_SOURCE_FILE_RECEIVED`.
|
||||||
|
The trigger installed by MARS-1409 will repopulate new records automatically.
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- MARS-1409: Add A_WORKFLOW_HISTORY_KEY column to A_SOURCE_FILE_RECEIVED (main package)
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409-POSTHOOK Master Installation Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Post-hook for MARS-1409 - Backfill A_WORKFLOW_HISTORY_KEY for
|
||||||
|
-- existing A_SOURCE_FILE_RECEIVED records by joining with ODS tables.
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-03-13
|
||||||
|
-- Prerequisites: MARS-1409 must be installed first (column must exist)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
SET VERIFY OFF
|
||||||
|
SET FEEDBACK ON
|
||||||
|
SET ECHO OFF
|
||||||
|
|
||||||
|
-- Create log directory if it doesn't exist
|
||||||
|
host mkdir log 2>nul
|
||||||
|
|
||||||
|
-- Generate dynamic SPOOL filename with timestamp
|
||||||
|
var filename VARCHAR2(100)
|
||||||
|
BEGIN
|
||||||
|
:filename := 'log/INSTALL_MARS_1409_POSTHOOK_' || SYS_CONTEXT('USERENV', 'CON_NAME') || '_' || TO_CHAR(SYSDATE,'YYYYMMDD_HH24MISS') || '.log';
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
column filename new_value _filename
|
||||||
|
select :filename filename from dual;
|
||||||
|
spool &_filename
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT MARS-1409-POSTHOOK Installation Starting
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Purpose: Backfill A_WORKFLOW_HISTORY_KEY for historical records
|
||||||
|
PROMPT in A_SOURCE_FILE_RECEIVED using matching ODS tables.
|
||||||
|
PROMPT
|
||||||
|
PROMPT This script will:
|
||||||
|
PROMPT - Update A_WORKFLOW_HISTORY_KEY for records with targeted PROCESSING_STATUS
|
||||||
|
PROMPT - Match records by SOURCE_FILE_NAME against file$name in ODS tables
|
||||||
|
PROMPT - Skip configs with no NULL records or missing ODS tables
|
||||||
|
PROMPT
|
||||||
|
PROMPT Prerequisite: MARS-1409 installed (A_WORKFLOW_HISTORY_KEY column exists)
|
||||||
|
PROMPT Expected Duration: 30-180 minutes (depends on data volume)
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
-- Confirm installation with user
|
||||||
|
ACCEPT continue CHAR PROMPT 'Type YES to continue with installation, or Ctrl+C to abort: '
|
||||||
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||||
|
BEGIN
|
||||||
|
IF '&continue' IS NULL OR TRIM('&continue') IS NULL OR UPPER(TRIM('&continue')) != 'YES' THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20000, 'Installation aborted by user');
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
WHENEVER SQLERROR CONTINUE
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT PREREQUISITE CHECK: Verifying MARS-1409 objects
|
||||||
|
PROMPT ============================================================================
|
||||||
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||||
|
DECLARE
|
||||||
|
vColCount NUMBER;
|
||||||
|
vTableCount NUMBER;
|
||||||
|
BEGIN
|
||||||
|
SELECT COUNT(*)
|
||||||
|
INTO vColCount
|
||||||
|
FROM ALL_TAB_COLUMNS
|
||||||
|
WHERE OWNER = 'CT_MRDS'
|
||||||
|
AND TABLE_NAME = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND COLUMN_NAME = 'A_WORKFLOW_HISTORY_KEY';
|
||||||
|
|
||||||
|
IF vColCount = 0 THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20001,
|
||||||
|
'Prerequisite failed: CT_MRDS.A_SOURCE_FILE_RECEIVED.A_WORKFLOW_HISTORY_KEY not found. Install MARS-1409 first (or do not run POSTHOOK after rollback).');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT COUNT(*)
|
||||||
|
INTO vTableCount
|
||||||
|
FROM ALL_TABLES
|
||||||
|
WHERE OWNER = 'CT_MRDS'
|
||||||
|
AND TABLE_NAME = 'A_WORKFLOW_HISTORY';
|
||||||
|
|
||||||
|
IF vTableCount = 0 THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20002,
|
||||||
|
'Prerequisite failed: CT_MRDS.A_WORKFLOW_HISTORY table not found.');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DBMS_OUTPUT.PUT_LINE('OK: Prerequisites satisfied (MARS-1409 schema changes detected).');
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
WHENEVER SQLERROR CONTINUE
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT STEP 1: Backfill A_WORKFLOW_HISTORY_KEY for existing records
|
||||||
|
PROMPT ============================================================================
|
||||||
|
@@01_MARS_1409_POSTHOOK_update_existing_workflow_keys.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT STEP 2: Diagnose workflow key status
|
||||||
|
PROMPT ============================================================================
|
||||||
|
@@02_MARS_1409_POSTHOOK_diagnose_workflow_key_status.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT MARS-1409-POSTHOOK Installation Complete
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Final Status:
|
||||||
|
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS install_end FROM DUAL;
|
||||||
|
PROMPT
|
||||||
|
PROMPT Review the log file for detailed results: &_filename
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
spool off
|
||||||
|
|
||||||
|
quit;
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409-POSTHOOK Master Rollback Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Rollback MARS-1409-POSTHOOK - Clear backfilled A_WORKFLOW_HISTORY_KEY
|
||||||
|
-- values from A_SOURCE_FILE_RECEIVED.
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-03-13
|
||||||
|
-- Note: This clears ALL non-NULL A_WORKFLOW_HISTORY_KEY values. The trigger
|
||||||
|
-- installed by MARS-1409 will repopulate them on next file processing.
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
SET VERIFY OFF
|
||||||
|
SET FEEDBACK ON
|
||||||
|
SET ECHO OFF
|
||||||
|
|
||||||
|
-- Create log directory if it doesn't exist
|
||||||
|
host mkdir log 2>nul
|
||||||
|
|
||||||
|
-- Generate dynamic SPOOL filename with timestamp
|
||||||
|
var filename VARCHAR2(100)
|
||||||
|
BEGIN
|
||||||
|
:filename := 'log/ROLLBACK_MARS_1409_POSTHOOK_' || SYS_CONTEXT('USERENV', 'CON_NAME') || '_' || TO_CHAR(SYSDATE,'YYYYMMDD_HH24MISS') || '.log';
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
column filename new_value _filename
|
||||||
|
select :filename filename from dual;
|
||||||
|
spool &_filename
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT MARS-1409-POSTHOOK Rollback Starting
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT This will reverse all changes from MARS-1409-POSTHOOK installation.
|
||||||
|
PROMPT
|
||||||
|
PROMPT Rollback steps:
|
||||||
|
PROMPT 1. Clear A_WORKFLOW_HISTORY_KEY values from A_SOURCE_FILE_RECEIVED
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
-- Confirm rollback with user
|
||||||
|
ACCEPT continue CHAR PROMPT 'Type YES to continue with rollback, or Ctrl+C to abort: '
|
||||||
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||||
|
BEGIN
|
||||||
|
IF '&continue' IS NULL OR TRIM('&continue') IS NULL OR UPPER(TRIM('&continue')) != 'YES' THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20000, 'Rollback aborted by user');
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
WHENEVER SQLERROR CONTINUE
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT STEP 1: Clear backfilled A_WORKFLOW_HISTORY_KEY values
|
||||||
|
PROMPT ============================================================================
|
||||||
|
@@91_MARS_1409_POSTHOOK_rollback_workflow_keys.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT MARS-1409-POSTHOOK Rollback Complete
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Final Status:
|
||||||
|
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS rollback_end FROM DUAL;
|
||||||
|
PROMPT
|
||||||
|
PROMPT Review the log file for detailed results: &_filename
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
spool off
|
||||||
|
|
||||||
|
quit;
|
||||||
26
MARS_Packages/REL02_POST/MARS-1409/.gitignore
vendored
Normal file
26
MARS_Packages/REL02_POST/MARS-1409/.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# MARS-1409 Package - Git Ignore Rules
|
||||||
|
# Standard exclusions for MARS deployment packages
|
||||||
|
|
||||||
|
# Confluence documentation (generated, not source)
|
||||||
|
confluence/
|
||||||
|
|
||||||
|
# Patches directory
|
||||||
|
patches/
|
||||||
|
|
||||||
|
# Log files from SPOOL operations
|
||||||
|
log/
|
||||||
|
|
||||||
|
# Test directories and files
|
||||||
|
test/
|
||||||
|
|
||||||
|
# Mock data scripts (development only)
|
||||||
|
mock_data/
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Editor backups
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Step 01: Add A_WORKFLOW_HISTORY_KEY column to A_SOURCE_FILE_RECEIVED
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Add A_WORKFLOW_HISTORY_KEY column to A_SOURCE_FILE_RECEIVED
|
||||||
|
-- using ALTER TABLE to preserve existing data.
|
||||||
|
-- Prerequisites: A_SOURCE_FILE_CONFIG table exists (FK dependency)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Adding A_WORKFLOW_HISTORY_KEY to A_SOURCE_FILE_RECEIVED...
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE 'ALTER TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED ADD (A_WORKFLOW_HISTORY_KEY NUMBER)';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Column A_WORKFLOW_HISTORY_KEY added to A_SOURCE_FILE_RECEIVED.');
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF SQLCODE = -1430 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SKIP: Column A_WORKFLOW_HISTORY_KEY already exists in A_SOURCE_FILE_RECEIVED.');
|
||||||
|
ELSE
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Adding comment on A_WORKFLOW_HISTORY_KEY...
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE q'[COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_WORKFLOW_HISTORY_KEY IS 'Direct link to workflow history - each file has exactly one workflow execution. Populated during VALIDATE_SOURCE_FILE_RECEIVED (MARS-1409)']';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Comment on A_WORKFLOW_HISTORY_KEY added.');
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Renaming IS_KEEP_IN_TRASH to IS_KEPT_IN_TRASH in A_SOURCE_FILE_CONFIG...
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE 'ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG RENAME COLUMN IS_KEEP_IN_TRASH TO IS_KEPT_IN_TRASH';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Column IS_KEEP_IN_TRASH renamed to IS_KEPT_IN_TRASH in A_SOURCE_FILE_CONFIG.');
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF SQLCODE = -904 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SKIP: Column IS_KEEP_IN_TRASH does not exist (already renamed or not present).');
|
||||||
|
ELSE
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 01 completed: A_WORKFLOW_HISTORY_KEY column added and IS_KEEP_IN_TRASH renamed to IS_KEPT_IN_TRASH.
|
||||||
|
PROMPT
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Step 10: Update A_TABLE_STAT, A_TABLE_STAT_HIST, A_SOURCE_FILE_CONFIG
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Apply MARS-1409 table changes:
|
||||||
|
-- - A_TABLE_STAT and A_TABLE_STAT_HIST: DROP and recreate from new_version
|
||||||
|
-- (stats tables with no critical persistent data)
|
||||||
|
-- - A_SOURCE_FILE_CONFIG: ALTER TABLE ADD IS_WORKFLOW_SUCCESS_REQUIRED column
|
||||||
|
-- (preserves existing configuration data)
|
||||||
|
-- - A_SOURCE_FILE_RECEIVED: no changes in this step
|
||||||
|
-- Prerequisites: A_SOURCE table exists (FK parent of A_SOURCE_FILE_CONFIG)
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- DROP A_TABLE_STAT
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Dropping A_TABLE_STAT...
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE 'DROP TABLE CT_MRDS.A_TABLE_STAT';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Table A_TABLE_STAT dropped.');
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF SQLCODE = -942 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SKIP: Table A_TABLE_STAT does not exist.');
|
||||||
|
ELSE
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- DROP A_TABLE_STAT_HIST
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Dropping A_TABLE_STAT_HIST...
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE 'DROP TABLE CT_MRDS.A_TABLE_STAT_HIST';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Table A_TABLE_STAT_HIST dropped.');
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF SQLCODE = -942 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SKIP: Table A_TABLE_STAT_HIST does not exist.');
|
||||||
|
ELSE
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- ADD IS_WORKFLOW_SUCCESS_REQUIRED to A_SOURCE_FILE_CONFIG
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Adding IS_WORKFLOW_SUCCESS_REQUIRED to A_SOURCE_FILE_CONFIG...
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE
|
||||||
|
'ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD ('
|
||||||
|
|| ' IS_WORKFLOW_SUCCESS_REQUIRED CHAR(1) DEFAULT ''Y'' NOT NULL '
|
||||||
|
|| ' CONSTRAINT CHK_IS_WORKFLOW_SUCCESS_REQUIRED CHECK (IS_WORKFLOW_SUCCESS_REQUIRED IN (''Y'', ''N''))'
|
||||||
|
|| ')';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Column IS_WORKFLOW_SUCCESS_REQUIRED added to A_SOURCE_FILE_CONFIG.');
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
IF SQLCODE = -1430 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SKIP: Column IS_WORKFLOW_SUCCESS_REQUIRED already exists in A_SOURCE_FILE_CONFIG.');
|
||||||
|
ELSE
|
||||||
|
RAISE;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Adding comment on IS_WORKFLOW_SUCCESS_REQUIRED...
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
EXECUTE IMMEDIATE q'[COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.IS_WORKFLOW_SUCCESS_REQUIRED IS 'Y=Archivization requires WORKFLOW_SUCCESSFUL=Y (standard DBT flow), N=Archive regardless of workflow completion status (bypass for manual/non-DBT sources). Added MARS-1409']';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Comment on IS_WORKFLOW_SUCCESS_REQUIRED added.');
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- RECREATE A_TABLE_STAT and A_TABLE_STAT_HIST from new_version
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Creating A_TABLE_STAT (new_version)...
|
||||||
|
@@new_version/A_TABLE_STAT.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Creating A_TABLE_STAT_HIST (new_version)...
|
||||||
|
@@new_version/A_TABLE_STAT_HIST.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 10 completed: A_TABLE_STAT and A_TABLE_STAT_HIST recreated from new_version scripts,
|
||||||
|
PROMPT IS_WORKFLOW_SUCCESS_REQUIRED column added to A_SOURCE_FILE_CONFIG (MARS-1409).
|
||||||
|
PROMPT
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Installation Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 01B_MARS_1409_install_CT_MRDS_ENV_MANAGER_SPEC.sql
|
||||||
|
-- Description: Install ENV_MANAGER v3.3.0 package specification
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- Dependencies: 01A_MARS_1409_update_existing_workflow_keys.sql
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT STEP 1B: Update ENV_MANAGER package specification
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
PROMPT Installing ENV_MANAGER package specification...
|
||||||
|
|
||||||
|
@@new_version/ENV_MANAGER.pkg
|
||||||
|
|
||||||
|
PROMPT ENV_MANAGER specification installed
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Installation Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 01C_MARS_1409_install_CT_MRDS_ENV_MANAGER_BODY.sql
|
||||||
|
-- Description: Install ENV_MANAGER v3.3.0 package body
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- Dependencies: 01B_MARS_1409_install_CT_MRDS_ENV_MANAGER_SPEC.sql
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT STEP 1C: Update ENV_MANAGER package body
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
PROMPT Installing ENV_MANAGER package body...
|
||||||
|
|
||||||
|
@@new_version/ENV_MANAGER.pkb
|
||||||
|
|
||||||
|
PROMPT ENV_MANAGER body installed
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Step 02: Install FILE_MANAGER Package Specification
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Deploy updated FILE_MANAGER package specification
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Installing FILE_MANAGER package specification...
|
||||||
|
|
||||||
|
-- Source from new_version directory
|
||||||
|
@@new_version/FILE_MANAGER.pkg
|
||||||
|
|
||||||
|
PROMPT FILE_MANAGER specification installed
|
||||||
|
PROMPT
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Step 03: Install FILE_MANAGER Package Body
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Deploy updated FILE_MANAGER package body
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Installing FILE_MANAGER package body...
|
||||||
|
|
||||||
|
-- Source from new_version directory
|
||||||
|
@@new_version/FILE_MANAGER.pkb
|
||||||
|
|
||||||
|
PROMPT FILE_MANAGER body installed
|
||||||
|
PROMPT
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Installation Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 03A_MARS_1409_install_CT_MRDS_FILE_ARCHIVER_SPEC.sql
|
||||||
|
-- Description: Install FILE_ARCHIVER package specification
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- Dependencies: 03_MARS_1409_install_CT_MRDS_FILE_MANAGER_BODY.sql
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT STEP 3A: Update FILE_ARCHIVER package specification
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
PROMPT Installing FILE_ARCHIVER package specification...
|
||||||
|
|
||||||
|
@@new_version/FILE_ARCHIVER.pkg
|
||||||
|
|
||||||
|
PROMPT FILE_ARCHIVER specification installed
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Installation Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 03B_MARS_1409_install_CT_MRDS_FILE_ARCHIVER_BODY.sql
|
||||||
|
-- Description: Install FILE_ARCHIVER package body
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- Dependencies: 03A_MARS_1409_install_CT_MRDS_FILE_ARCHIVER_SPEC.sql
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT STEP 3B: Update FILE_ARCHIVER package body
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
PROMPT Installing FILE_ARCHIVER package body...
|
||||||
|
|
||||||
|
@@new_version/FILE_ARCHIVER.pkb
|
||||||
|
|
||||||
|
PROMPT FILE_ARCHIVER body installed
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Step 08: Install A_WORKFLOW_HISTORY trigger
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Update trigger to mark A_SOURCE_FILE_RECEIVED as INGESTED
|
||||||
|
-- when WORKFLOW_SUCCESSFUL is set to 'Y'
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT Installing A_WORKFLOW_HISTORY (new_version)...
|
||||||
|
@@new_version/A_WORKFLOW_HISTORY.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
DECLARE
|
||||||
|
v_status VARCHAR2(20);
|
||||||
|
BEGIN
|
||||||
|
SELECT status INTO v_status
|
||||||
|
FROM all_objects
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND object_name = 'A_WORKFLOW_HISTORY'
|
||||||
|
AND object_type = 'TRIGGER';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('A_WORKFLOW_HISTORY status: ' || v_status);
|
||||||
|
IF v_status != 'VALID' THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20002, 'ERROR: A_WORKFLOW_HISTORY compiled with errors (status=' || v_status || '). Installation aborted.');
|
||||||
|
END IF;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN NO_DATA_FOUND THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20001, 'ERROR: A_WORKFLOW_HISTORY not found after installation');
|
||||||
|
END;
|
||||||
|
/
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Step 04: Verify Installation
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Verify successful installation of MARS-1409 changes
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
SET VERIFY OFF
|
||||||
|
SET FEEDBACK ON
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Verifying MARS-1409 Installation
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
-- Check if column was added
|
||||||
|
PROMPT
|
||||||
|
PROMPT 1. Checking A_WORKFLOW_HISTORY_KEY column existence...
|
||||||
|
SELECT
|
||||||
|
column_name,
|
||||||
|
data_type,
|
||||||
|
data_length,
|
||||||
|
nullable
|
||||||
|
FROM all_tab_columns
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND column_name = 'A_WORKFLOW_HISTORY_KEY';
|
||||||
|
|
||||||
|
-- Check foreign key constraint
|
||||||
|
PROMPT
|
||||||
|
PROMPT 2. Checking foreign key constraint...
|
||||||
|
SELECT
|
||||||
|
constraint_name,
|
||||||
|
constraint_type,
|
||||||
|
r_constraint_name,
|
||||||
|
status
|
||||||
|
FROM all_constraints
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND constraint_type = 'R'
|
||||||
|
AND constraint_name LIKE '%WORKFLOW_HISTORY%';
|
||||||
|
|
||||||
|
-- Check package compilation status
|
||||||
|
PROMPT
|
||||||
|
PROMPT 3. Checking FILE_MANAGER package compilation...
|
||||||
|
SELECT
|
||||||
|
object_name,
|
||||||
|
object_type,
|
||||||
|
status,
|
||||||
|
last_ddl_time
|
||||||
|
FROM all_objects
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND object_name = 'FILE_MANAGER'
|
||||||
|
AND object_type IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
|
ORDER BY object_type;
|
||||||
|
|
||||||
|
-- Check for compilation errors
|
||||||
|
PROMPT
|
||||||
|
PROMPT 4. Checking for compilation errors...
|
||||||
|
SELECT
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
line,
|
||||||
|
position,
|
||||||
|
text
|
||||||
|
FROM all_errors
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND name = 'FILE_MANAGER'
|
||||||
|
ORDER BY type, line, position;
|
||||||
|
|
||||||
|
-- Check FILE_ARCHIVER compilation status
|
||||||
|
PROMPT
|
||||||
|
PROMPT 5. Checking FILE_ARCHIVER package compilation...
|
||||||
|
SELECT
|
||||||
|
object_name,
|
||||||
|
object_type,
|
||||||
|
status,
|
||||||
|
last_ddl_time
|
||||||
|
FROM all_objects
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND object_name = 'FILE_ARCHIVER'
|
||||||
|
AND object_type IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
|
ORDER BY object_type;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
line,
|
||||||
|
position,
|
||||||
|
text
|
||||||
|
FROM all_errors
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND name = 'FILE_ARCHIVER'
|
||||||
|
ORDER BY type, line, position;
|
||||||
|
|
||||||
|
-- Check DATA_EXPORTER compilation status
|
||||||
|
PROMPT
|
||||||
|
PROMPT 5C. Checking DATA_EXPORTER package compilation...
|
||||||
|
SELECT
|
||||||
|
object_name,
|
||||||
|
object_type,
|
||||||
|
status,
|
||||||
|
last_ddl_time
|
||||||
|
FROM all_objects
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND object_name = 'DATA_EXPORTER'
|
||||||
|
AND object_type IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
|
ORDER BY object_type;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
line,
|
||||||
|
position,
|
||||||
|
text
|
||||||
|
FROM all_errors
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND name = 'DATA_EXPORTER'
|
||||||
|
ORDER BY type, line, position;
|
||||||
|
|
||||||
|
-- Check trigger status
|
||||||
|
PROMPT
|
||||||
|
PROMPT 5B. Checking A_WORKFLOW_HISTORY trigger...
|
||||||
|
SELECT
|
||||||
|
trigger_name,
|
||||||
|
trigger_type,
|
||||||
|
triggering_event,
|
||||||
|
status
|
||||||
|
FROM all_triggers
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND trigger_name = 'A_WORKFLOW_HISTORY';
|
||||||
|
|
||||||
|
-- Verify package versions
|
||||||
|
PROMPT
|
||||||
|
PROMPT 6. Verifying package versions...
|
||||||
|
SELECT 'FILE_MANAGER' AS PACKAGE_NAME, CT_MRDS.FILE_MANAGER.GET_VERSION() AS VERSION FROM DUAL
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'ENV_MANAGER' AS PACKAGE_NAME, CT_MRDS.ENV_MANAGER.GET_VERSION() AS VERSION FROM DUAL
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'FILE_ARCHIVER' AS PACKAGE_NAME, CT_MRDS.FILE_ARCHIVER.GET_VERSION() AS VERSION FROM DUAL
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'DATA_EXPORTER' AS PACKAGE_NAME, CT_MRDS.DATA_EXPORTER.GET_VERSION() AS VERSION FROM DUAL;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Verification Complete
|
||||||
|
PROMPT ============================================================================
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Step 11: Install DATA_EXPORTER Package Specification
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 11_MARS_1409_install_CT_MRDS_DATA_EXPORTER_SPEC.sql
|
||||||
|
-- Description: Install DATA_EXPORTER package specification (new version)
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Installing DATA_EXPORTER package specification...
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
@@new_version/DATA_EXPORTER.pkg
|
||||||
|
|
||||||
|
PROMPT DATA_EXPORTER specification installed
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Step 12: Install DATA_EXPORTER Package Body
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 12_MARS_1409_install_CT_MRDS_DATA_EXPORTER_BODY.sql
|
||||||
|
-- Description: Install DATA_EXPORTER package body (new version)
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Installing DATA_EXPORTER package body...
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
@@new_version/DATA_EXPORTER.pkb
|
||||||
|
|
||||||
|
PROMPT DATA_EXPORTER body installed
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Rollback Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 83_MARS_1409_rollback_CT_MRDS_DATA_EXPORTER_SPEC.sql
|
||||||
|
-- Description: Restore DATA_EXPORTER package specification (previous version)
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Restoring DATA_EXPORTER package specification...
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
@@rollback_version/DATA_EXPORTER.pkg
|
||||||
|
|
||||||
|
PROMPT DATA_EXPORTER specification restored
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Rollback Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 84_MARS_1409_rollback_CT_MRDS_DATA_EXPORTER_BODY.sql
|
||||||
|
-- Description: Restore DATA_EXPORTER package body (previous version)
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Restoring DATA_EXPORTER package body...
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
@@rollback_version/DATA_EXPORTER.pkb
|
||||||
|
|
||||||
|
PROMPT DATA_EXPORTER body restored
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Rollback 90: Verify Rollback
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Verify successful rollback of MARS-1409 changes
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Verifying MARS-1409 Rollback
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
-- Check if column was removed
|
||||||
|
PROMPT
|
||||||
|
PROMPT 1. Verifying A_WORKFLOW_HISTORY_KEY column removal...
|
||||||
|
DECLARE
|
||||||
|
v_count NUMBER;
|
||||||
|
BEGIN
|
||||||
|
SELECT COUNT(*)
|
||||||
|
INTO v_count
|
||||||
|
FROM all_tab_columns
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND table_name = 'A_SOURCE_FILE_RECEIVED'
|
||||||
|
AND column_name = 'A_WORKFLOW_HISTORY_KEY';
|
||||||
|
|
||||||
|
IF v_count = 0 THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('SUCCESS: A_WORKFLOW_HISTORY_KEY column removed');
|
||||||
|
ELSE
|
||||||
|
DBMS_OUTPUT.PUT_LINE('WARNING: A_WORKFLOW_HISTORY_KEY column still exists');
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
-- Check trigger was restored
|
||||||
|
PROMPT
|
||||||
|
PROMPT 1B. Checking A_WORKFLOW_HISTORY trigger status...
|
||||||
|
DECLARE
|
||||||
|
v_status VARCHAR2(20);
|
||||||
|
BEGIN
|
||||||
|
SELECT status INTO v_status
|
||||||
|
FROM all_objects
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND object_name = 'A_WORKFLOW_HISTORY'
|
||||||
|
AND object_type = 'TRIGGER';
|
||||||
|
DBMS_OUTPUT.PUT_LINE('A_WORKFLOW_HISTORY status: ' || v_status);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN NO_DATA_FOUND THEN
|
||||||
|
DBMS_OUTPUT.PUT_LINE('WARNING: A_WORKFLOW_HISTORY not found');
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
-- Check compilation status
|
||||||
|
PROMPT
|
||||||
|
PROMPT 2. Checking package compilation status...
|
||||||
|
SELECT
|
||||||
|
object_name,
|
||||||
|
object_type,
|
||||||
|
status,
|
||||||
|
last_ddl_time
|
||||||
|
FROM all_objects
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND object_name IN ('FILE_MANAGER', 'ENV_MANAGER', 'FILE_ARCHIVER', 'DATA_EXPORTER')
|
||||||
|
AND object_type IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
|
ORDER BY object_name, object_type;
|
||||||
|
|
||||||
|
-- Check for compilation errors
|
||||||
|
PROMPT
|
||||||
|
PROMPT 3. Checking for compilation errors...
|
||||||
|
SELECT name, type, line, position, text
|
||||||
|
FROM all_errors
|
||||||
|
WHERE owner = 'CT_MRDS'
|
||||||
|
AND name IN ('FILE_MANAGER', 'ENV_MANAGER', 'FILE_ARCHIVER', 'DATA_EXPORTER')
|
||||||
|
ORDER BY name, type, line, position;
|
||||||
|
|
||||||
|
-- Verify package versions
|
||||||
|
PROMPT
|
||||||
|
PROMPT 4. Verifying package versions after rollback...
|
||||||
|
SELECT 'FILE_MANAGER' AS PACKAGE_NAME, CT_MRDS.FILE_MANAGER.GET_VERSION() AS VERSION FROM DUAL
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'ENV_MANAGER' AS PACKAGE_NAME, CT_MRDS.ENV_MANAGER.GET_VERSION() AS VERSION FROM DUAL
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'FILE_ARCHIVER' AS PACKAGE_NAME, CT_MRDS.FILE_ARCHIVER.GET_VERSION() AS VERSION FROM DUAL
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'DATA_EXPORTER' AS PACKAGE_NAME, CT_MRDS.DATA_EXPORTER.GET_VERSION() AS VERSION FROM DUAL;
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Rollback Verification Complete
|
||||||
|
PROMPT ============================================================================
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Rollback Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 93B_MARS_1409_rollback_FILE_ARCHIVER_SPEC.sql
|
||||||
|
-- Description: Restore FILE_ARCHIVER package specification (previous version)
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Restoring FILE_ARCHIVER package specification...
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
@@rollback_version/FILE_ARCHIVER.pkg
|
||||||
|
|
||||||
|
PROMPT FILE_ARCHIVER specification restored
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Rollback Script
|
||||||
|
-- ============================================================================
|
||||||
|
-- Script: 93A_MARS_1409_rollback_FILE_ARCHIVER_BODY.sql
|
||||||
|
-- Description: Restore FILE_ARCHIVER package body (previous version)
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: 2026-02-27
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
PROMPT ============================================================================
|
||||||
|
PROMPT Restoring FILE_ARCHIVER package body...
|
||||||
|
PROMPT ============================================================================
|
||||||
|
|
||||||
|
@@rollback_version/FILE_ARCHIVER.pkb
|
||||||
|
|
||||||
|
PROMPT FILE_ARCHIVER body restored
|
||||||
|
|
||||||
|
/
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- MARS-1409 Rollback 92: Restore FILE_MANAGER Package Specification
|
||||||
|
-- ============================================================================
|
||||||
|
-- Purpose: Restore previous FILE_MANAGER package specification
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
SET SERVEROUTPUT ON SIZE UNLIMITED
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Restoring FILE_MANAGER package specification...
|
||||||
|
|
||||||
|
-- Source from rollback_version directory
|
||||||
|
@@rollback_version/FILE_MANAGER.pkg
|
||||||
|
|
||||||
|
PROMPT FILE_MANAGER specification restored
|
||||||
|
PROMPT
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user