Compare commits
39 Commits
3848a9471b
...
866b886c70
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
866b886c70 | ||
|
|
cafa30f8f3 | ||
|
|
a0f4146a24 | ||
|
|
2b116c0256 | ||
|
|
204616252a | ||
|
|
8ce07c3360 | ||
|
|
64dc830a2b | ||
|
|
057a4e7ce3 | ||
|
|
a9a51f19be | ||
|
|
fc6304c60b | ||
|
|
b6f6446232 | ||
|
|
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 |
@@ -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,
|
||||||
|
ARCHIVE_ENABLED CHAR(1) DEFAULT 'N' NOT NULL,
|
||||||
|
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_ARCHIVE_ENABLED CHECK (ARCHIVE_ENABLED IN ('Y', 'N'));
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG ADD CONSTRAINT
|
||||||
|
CHK_KEEP_IN_TRASH CHECK (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.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.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', 'ARCHIVE_ENABLED', 'KEEP_IN_TRASH')
|
||||||
ORDER BY column_id;
|
ORDER BY column_id;
|
||||||
|
|
||||||
PROMPT ========================================
|
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
|
||||||
|
--=============================================================================================================================
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ SELECT CT_MRDS.FILE_ARCHIVER.GET_VERSION() as package_version FROM DUAL;
|
|||||||
-- 7. Test trigger validation
|
-- 7. Test trigger validation
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT 7. Testing trigger validation (should fail)...
|
PROMPT 7. Testing trigger validation (should fail)...
|
||||||
|
WHENEVER SQLERROR CONTINUE
|
||||||
|
SET SERVEROUTPUT ON
|
||||||
DECLARE
|
DECLARE
|
||||||
vTestPassed BOOLEAN := FALSE;
|
vTestPassed BOOLEAN := FALSE;
|
||||||
BEGIN
|
BEGIN
|
||||||
@@ -107,14 +109,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=6, 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 = 6
|
||||||
|
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',
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD = 10,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD = 100000,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD = 1073741824, -- 1 GB
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS = 24,
|
||||||
|
ARCHIVE_ENABLED = 'Y', -- Enable archival for all LM tables
|
||||||
|
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 = 6)
|
||||||
|
PROMPT =====================================================================
|
||||||
|
PROMPT Thresholds: 5 files OR 50K rows OR 512MB
|
||||||
|
PROMPT Stats expire: 48 hours
|
||||||
|
PROMPT =====================================================================
|
||||||
|
|
||||||
|
-- Update CSDB DEBT tables (6-month retention)
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 6,
|
||||||
|
ODS_SCHEMA_NAME = 'ODS',
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD = 5,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD = 50000,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD = 536870912, -- 512 MB
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS = 48,
|
||||||
|
ARCHIVE_ENABLED = 'Y', -- Enable archival for CSDB DEBT tables
|
||||||
|
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',
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD = 10,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD = 20000,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD = 268435456, -- 256 MB
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS = 72,
|
||||||
|
ARCHIVE_ENABLED = 'Y', -- Enable archival for CSDB rating/description tables
|
||||||
|
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,
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD AS FILE_THR,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD AS ROW_THR,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
ARCHIVE_ENABLED,
|
||||||
|
KEEP_IN_TRASH,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS'
|
||||||
|
AND MINIMUM_AGE_MONTHS = 0
|
||||||
|
AND FILES_COUNT_OVER_ARCHIVE_THRESHOLD = 10
|
||||||
|
AND ROWS_COUNT_OVER_ARCHIVE_THRESHOLD = 100000
|
||||||
|
AND BYTES_SUM_OVER_ARCHIVE_THRESHOLD = 1073741824
|
||||||
|
AND HOURS_TO_EXPIRE_STATISTICS = 24
|
||||||
|
AND ARCHIVE_ENABLED = 'Y'
|
||||||
|
AND 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 = 6):
|
||||||
|
PROMPT
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD AS FILE_THR,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD AS ROW_THR,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
ARCHIVE_ENABLED,
|
||||||
|
KEEP_IN_TRASH,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS'
|
||||||
|
AND MINIMUM_AGE_MONTHS = 6
|
||||||
|
AND FILES_COUNT_OVER_ARCHIVE_THRESHOLD = 5
|
||||||
|
AND ROWS_COUNT_OVER_ARCHIVE_THRESHOLD = 50000
|
||||||
|
AND BYTES_SUM_OVER_ARCHIVE_THRESHOLD = 536870912
|
||||||
|
AND HOURS_TO_EXPIRE_STATISTICS = 48
|
||||||
|
AND ARCHIVE_ENABLED = 'Y'
|
||||||
|
AND 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,
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD AS FILE_THR,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD AS ROW_THR,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
ARCHIVE_ENABLED,
|
||||||
|
KEEP_IN_TRASH,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS'
|
||||||
|
AND MINIMUM_AGE_MONTHS = 0
|
||||||
|
AND FILES_COUNT_OVER_ARCHIVE_THRESHOLD = 10
|
||||||
|
AND ROWS_COUNT_OVER_ARCHIVE_THRESHOLD = 20000
|
||||||
|
AND BYTES_SUM_OVER_ARCHIVE_THRESHOLD = 268435456
|
||||||
|
AND HOURS_TO_EXPIRE_STATISTICS = 72
|
||||||
|
AND ARCHIVE_ENABLED = 'Y'
|
||||||
|
AND 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 FILES_COUNT_OVER_ARCHIVE_THRESHOLD IS NOT NULL THEN 1 ELSE 0 END) AS WITH_FILE_THRESHOLD,
|
||||||
|
SUM(CASE WHEN ROWS_COUNT_OVER_ARCHIVE_THRESHOLD IS NOT NULL THEN 1 ELSE 0 END) AS WITH_ROWS_THRESHOLD,
|
||||||
|
SUM(CASE WHEN BYTES_SUM_OVER_ARCHIVE_THRESHOLD 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 ARCHIVE_ENABLED = 'Y' THEN 1 ELSE 0 END) AS ARCHIVAL_ENABLED,
|
||||||
|
SUM(CASE WHEN 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(FILES_COUNT_OVER_ARCHIVE_THRESHOLD) AS FILES_THRESHOLD,
|
||||||
|
MAX(ROWS_COUNT_OVER_ARCHIVE_THRESHOLD) AS ROWS_THRESHOLD,
|
||||||
|
ROUND(MAX(BYTES_SUM_OVER_ARCHIVE_THRESHOLD)/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,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,20 +1,28 @@
|
|||||||
-- 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, ARCHIVE_ENABLED, and 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_ARCHIVE_ENABLED;
|
||||||
|
|
||||||
|
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
DROP CONSTRAINT CHK_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,
|
||||||
|
ARCHIVE_ENABLED,
|
||||||
|
KEEP_IN_TRASH
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Verify columns dropped
|
-- Verify columns dropped
|
||||||
@@ -23,8 +31,8 @@ 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', 'ARCHIVE_ENABLED', 'KEEP_IN_TRASH');
|
||||||
|
|
||||||
PROMPT ========================================
|
PROMPT ========================================
|
||||||
PROMPT Archival strategy columns removed successfully
|
PROMPT Archival strategy and config columns removed successfully
|
||||||
PROMPT ========================================
|
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
|
||||||
|
-- - FILES_COUNT_OVER_ARCHIVE_THRESHOLD
|
||||||
|
-- - ROWS_COUNT_OVER_ARCHIVE_THRESHOLD
|
||||||
|
-- - BYTES_SUM_OVER_ARCHIVE_THRESHOLD
|
||||||
|
-- - 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,
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD = NULL,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD = NULL,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD = 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,
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD = NULL,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD = NULL,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD = 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,
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD = NULL,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD = NULL,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD = 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,
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD AS FILE_THR,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD AS ROW_THR,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY IS NULL
|
||||||
|
AND MINIMUM_AGE_MONTHS IS NULL
|
||||||
|
AND FILES_COUNT_OVER_ARCHIVE_THRESHOLD IS NULL
|
||||||
|
AND ROWS_COUNT_OVER_ARCHIVE_THRESHOLD IS NULL
|
||||||
|
AND BYTES_SUM_OVER_ARCHIVE_THRESHOLD 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,
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD AS FILE_THR,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD AS ROW_THR,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY IS NULL
|
||||||
|
AND MINIMUM_AGE_MONTHS IS NULL
|
||||||
|
AND FILES_COUNT_OVER_ARCHIVE_THRESHOLD IS NULL
|
||||||
|
AND ROWS_COUNT_OVER_ARCHIVE_THRESHOLD IS NULL
|
||||||
|
AND BYTES_SUM_OVER_ARCHIVE_THRESHOLD 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,
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD AS FILE_THR,
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD AS ROW_THR,
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD AS BYTE_THR,
|
||||||
|
HOURS_TO_EXPIRE_STATISTICS AS STATS_HRS,
|
||||||
|
CASE
|
||||||
|
WHEN ARCHIVAL_STRATEGY IS NULL
|
||||||
|
AND MINIMUM_AGE_MONTHS IS NULL
|
||||||
|
AND FILES_COUNT_OVER_ARCHIVE_THRESHOLD IS NULL
|
||||||
|
AND ROWS_COUNT_OVER_ARCHIVE_THRESHOLD IS NULL
|
||||||
|
AND BYTES_SUM_OVER_ARCHIVE_THRESHOLD 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 =====================================================================
|
||||||
@@ -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
|
||||||
@@ -35,9 +36,9 @@ 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
|
||||||
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
|
||||||
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: 10 (DDL, Trigger, Statuses, Grants, Package v3.3.0, 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,56 @@ 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/9: 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/9: 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 3/10: Adding TRASH retention statuses to A_SOURCE_FILE_RECEIVED
|
||||||
PROMPT ===============================================================
|
PROMPT =====================================================================
|
||||||
|
@@07_MARS_828_install_add_trash_retention_statuses.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 4/10: Granting privileges on T_FILENAME to MRDS_LOADER
|
||||||
|
PROMPT ============================================================
|
||||||
|
@@08_MARS_828_install_grant_t_filename.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 5/10: 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 6/10: 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 7/10: Verifying installation
|
||||||
PROMPT =================================
|
PROMPT =================================
|
||||||
@@05_MARS_828_verify_installation.sql
|
@@05_MARS_828_verify_installation.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 6/7: Tracking package versions
|
PROMPT Step 8/10: Tracking package versions
|
||||||
PROMPT ====================================
|
PROMPT ====================================
|
||||||
@@track_package_versions.sql
|
@@track_package_versions.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 7/7: Verifying tracked packages
|
PROMPT Step 9/10: Verifying tracked packages
|
||||||
PROMPT =====================================
|
PROMPT =====================================
|
||||||
@@verify_packages_version.sql
|
@@verify_packages_version.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 10/10: 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
|
||||||
@@ -97,16 +114,21 @@ 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 - Package: CT_MRDS.FILE_ARCHIVER
|
||||||
PROMPT - Version: 2.0.0 -> 3.0.0 (MAJOR)
|
PROMPT - Version: 3.3.0 (includes selective archiving and config-based TRASH policy)
|
||||||
PROMPT - New Strategies: CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID
|
PROMPT - Strategies: THRESHOLD_BASED (default), MINIMUM_AGE_MONTHS (0=current month), HYBRID
|
||||||
PROMPT - Backward Compatible: THRESHOLD_BASED (default)
|
PROMPT - Selective Archiving: ARCHIVE_ENABLED column (Y=archive, N=skip)
|
||||||
|
PROMPT - TRASH Policy: KEEP_IN_TRASH column (Y=keep files, N=delete immediately)
|
||||||
|
PROMPT * Default: ARCHIVE_ENABLED='Y', 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,56 @@
|
|||||||
|
-- ====================================================================
|
||||||
|
-- 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),
|
||||||
|
DAYS_FOR_ARCHIVE_THRESHOLD NUMBER(4,0),
|
||||||
|
FILES_COUNT_OVER_ARCHIVE_THRESHOLD NUMBER(38,0),
|
||||||
|
BYTES_SUM_OVER_ARCHIVE_THRESHOLD NUMBER(38,0),
|
||||||
|
ODS_SCHEMA_NAME VARCHAR2(100),
|
||||||
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD 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',
|
||||||
|
ARCHIVE_ENABLED CHAR(1) DEFAULT 'N' NOT NULL,
|
||||||
|
KEEP_IN_TRASH CHAR(1) DEFAULT 'N' NOT NULL,
|
||||||
|
CONSTRAINT A_SOURCE_FILE_CONFIG_PK PRIMARY KEY (A_SOURCE_FILE_CONFIG_KEY),
|
||||||
|
CONSTRAINT CHK_ARCHIVE_ENABLED CHECK (ARCHIVE_ENABLED IN ('Y', 'N')),
|
||||||
|
CONSTRAINT CHK_KEEP_IN_TRASH CHECK (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.ARCHIVAL_STRATEGY IS 'Archival strategy: THRESHOLD_BASED, CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID. Added in MARS-828';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.MINIMUM_AGE_MONTHS IS 'Minimum age in months before archival (required for MINIMUM_AGE_MONTHS strategy). Added in MARS-828';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING IS 'Oracle character set name for CSV files (e.g., UTF8, WE8MSWIN1252, EE8ISO8859P2). Added in MARS-1049';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.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.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';
|
||||||
|
|
||||||
|
GRANT SELECT, INSERT, UPDATE, DELETE ON CT_MRDS.A_SOURCE_FILE_CONFIG TO MRDS_LOADER_ROLE;
|
||||||
@@ -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', '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);
|
||||||
|
|
||||||
|
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 ARCHIVE_ENABLED and 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.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.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 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 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 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 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 ARCHIVE_ENABLED='Y'.
|
||||||
|
* TRASH policy for each table is controlled by individual 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
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -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,15 @@ 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. Drop all configuration columns (ARCHIVAL_STRATEGY, MINIMUM_AGE_MONTHS, ARCHIVE_ENABLED, KEEP_IN_TRASH)
|
||||||
|
PROMPT 5. Restore FILE_ARCHIVER package to v2.0.0
|
||||||
|
PROMPT 6. 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,32 +56,37 @@ 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/7: 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/7: 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/7: 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/7: Dropping all archival configuration columns
|
||||||
PROMPT =============================================
|
PROMPT ======================================================
|
||||||
@@94_MARS_828_rollback_columns.sql
|
@@94_MARS_828_rollback_columns.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Step 5/6: Tracking rollback version
|
PROMPT Step 5/7: 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 6/7: Restoring FILE_ARCHIVER Package Body v2.0.0
|
||||||
|
PROMPT ======================================================
|
||||||
|
@@92_MARS_828_rollback_FILE_ARCHIVER_BODY.sql
|
||||||
|
|
||||||
|
PROMPT
|
||||||
|
PROMPT Step 7/7: Verifying tracked packages
|
||||||
PROMPT =====================================
|
PROMPT =====================================
|
||||||
@@verify_packages_version.sql
|
@@verify_packages_version.sql
|
||||||
|
|
||||||
|
|||||||
@@ -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 ========================================
|
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- MARS-1057: Install FILE_MANAGER Package Specification v3.4.0
|
-- MARS-1057: Install FILE_MANAGER Package Specification v3.5.0
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- Purpose: Deploy FILE_MANAGER package specification with new batch external table creation procedures
|
-- Purpose: Deploy FILE_MANAGER package specification with batch external table creation and area filter functionality
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
-- Related: MARS-1057 Batch External Table Creation
|
-- Related: MARS-1057 Batch External Table Creation + Area Filter Enhancement
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON
|
SET SERVEROUTPUT ON
|
||||||
|
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT Installing FILE_MANAGER Package Specification v3.4.0
|
PROMPT Installing FILE_MANAGER Package Specification v3.5.0
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
|
|
||||||
@@new_version/FILE_MANAGER.pkg
|
@@new_version/FILE_MANAGER.pkg
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- MARS-1057: Install FILE_MANAGER Package Body v3.4.0
|
-- MARS-1057: Install FILE_MANAGER Package Body v3.5.0
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- Purpose: Deploy FILE_MANAGER package body with implementation of batch external table creation procedures
|
-- Purpose: Deploy FILE_MANAGER package body with batch external table creation and area filter functionality
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
-- Related: MARS-1057 Batch External Table Creation
|
-- Related: MARS-1057 Batch External Table Creation + Area Filter Enhancement
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON
|
SET SERVEROUTPUT ON
|
||||||
|
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT Installing FILE_MANAGER Package Body v3.4.0
|
PROMPT Installing FILE_MANAGER Package Body v3.5.0
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
|
|
||||||
@@new_version/FILE_MANAGER.pkb
|
@@new_version/FILE_MANAGER.pkb
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- MARS-1057: Install ODS.FILE_MANAGER_ODS Package Specification
|
-- MARS-1057: Install ODS.FILE_MANAGER_ODS Package Specification
|
||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- Purpose: Deploy FILE_MANAGER_ODS package specification v2.2.0
|
-- Purpose: Deploy FILE_MANAGER_ODS package specification v2.4.0
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
-- Package: ODS.FILE_MANAGER_ODS
|
-- Package: ODS.FILE_MANAGER_ODS
|
||||||
-- Version: 2.1.0 -> 2.2.0
|
-- Version: 2.1.0 -> 2.4.0
|
||||||
-- Changes: Added CREATE_EXTERNAL_TABLES_SET and CREATE_EXTERNAL_TABLES_BATCH wrappers
|
-- Changes: Added CREATE_EXTERNAL_TABLES_SET and CREATE_EXTERNAL_TABLES_BATCH wrappers with pArea and pRestoreGrants parameters
|
||||||
|
|
||||||
SET ECHO ON
|
SET ECHO ON
|
||||||
SET DEFINE OFF
|
SET DEFINE OFF
|
||||||
|
|
||||||
PROMPT Installing ODS.FILE_MANAGER_ODS Package Specification v2.2.0...
|
PROMPT Installing ODS.FILE_MANAGER_ODS Package Specification v2.4.0...
|
||||||
|
|
||||||
@@new_version/FILE_MANAGER_ODS.pkg
|
@@new_version/FILE_MANAGER_ODS.pkg
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- MARS-1057: Install ODS.FILE_MANAGER_ODS Package Body
|
-- MARS-1057: Install ODS.FILE_MANAGER_ODS Package Body
|
||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- Purpose: Deploy FILE_MANAGER_ODS package body v2.2.0
|
-- Purpose: Deploy FILE_MANAGER_ODS package body v2.4.0
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
-- Package: ODS.FILE_MANAGER_ODS
|
-- Package: ODS.FILE_MANAGER_ODS
|
||||||
-- Version: 2.1.0 -> 2.2.0
|
-- Version: 2.1.0 -> 2.4.0
|
||||||
-- Changes: Added CREATE_EXTERNAL_TABLES_SET and CREATE_EXTERNAL_TABLES_BATCH wrapper implementations
|
-- Changes: Added CREATE_EXTERNAL_TABLES_SET and CREATE_EXTERNAL_TABLES_BATCH wrapper implementations with pArea and pRestoreGrants parameters
|
||||||
|
|
||||||
SET ECHO ON
|
SET ECHO ON
|
||||||
SET DEFINE OFF
|
SET DEFINE OFF
|
||||||
|
|
||||||
PROMPT Installing ODS.FILE_MANAGER_ODS Package Body v2.2.0...
|
PROMPT Installing ODS.FILE_MANAGER_ODS Package Body v2.4.0...
|
||||||
|
|
||||||
@@new_version/FILE_MANAGER_ODS.pkb
|
@@new_version/FILE_MANAGER_ODS.pkb
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- MARS-1057: Rollback FILE_MANAGER Package Specification to v3.3.0
|
-- MARS-1057: Rollback FILE_MANAGER Package Specification to v3.3.0
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- Purpose: Restore FILE_MANAGER package specification to version before MARS-1057 changes
|
-- Purpose: Restore FILE_MANAGER package specification to version before MARS-1057 changes (from v3.5.0 to v3.3.0)
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
-- Related: MARS-1057 Batch External Table Creation (ROLLBACK)
|
-- Related: MARS-1057 Batch External Table Creation + Area Filter (ROLLBACK)
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON
|
SET SERVEROUTPUT ON
|
||||||
|
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT Rolling back FILE_MANAGER Package Specification to v3.3.0
|
PROMPT Rolling back FILE_MANAGER Package Specification from v3.5.0 to v3.3.0
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
|
|
||||||
@@current_version/FILE_MANAGER.pkg
|
@@rollback_version/FILE_MANAGER.pkg
|
||||||
|
|
||||||
-- Verify compilation status (check specific schema when installing as ADMIN)
|
-- Verify compilation status (check specific schema when installing as ADMIN)
|
||||||
SELECT object_name, object_type, status
|
SELECT object_name, object_type, status
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- MARS-1057: Rollback FILE_MANAGER Package Body to v3.3.0
|
-- MARS-1057: Rollback FILE_MANAGER Package Body to v3.3.0
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
-- Purpose: Restore FILE_MANAGER package body to version before MARS-1057 changes
|
-- Purpose: Restore FILE_MANAGER package body to version before MARS-1057 changes (from v3.5.0 to v3.3.0)
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
-- Related: MARS-1057 Batch External Table Creation (ROLLBACK)
|
-- Related: MARS-1057 Batch External Table Creation + Area Filter (ROLLBACK)
|
||||||
--=============================================================================================================================
|
--=============================================================================================================================
|
||||||
|
|
||||||
SET SERVEROUTPUT ON
|
SET SERVEROUTPUT ON
|
||||||
|
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
PROMPT Rolling back FILE_MANAGER Package Body to v3.3.0
|
PROMPT Rolling back FILE_MANAGER Package Body from v3.5.0 to v3.3.0
|
||||||
PROMPT ========================================================================
|
PROMPT ========================================================================
|
||||||
|
|
||||||
@@current_version/FILE_MANAGER.pkb
|
@@rollback_version/FILE_MANAGER.pkb
|
||||||
|
|
||||||
-- Verify compilation status (check specific schema when installing as ADMIN)
|
-- Verify compilation status (check specific schema when installing as ADMIN)
|
||||||
SELECT object_name, object_type, status
|
SELECT object_name, object_type, status
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- Purpose: Restore FILE_MANAGER_ODS package body to v2.1.0
|
-- Purpose: Restore FILE_MANAGER_ODS package body to v2.1.0
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
-- Package: ODS.FILE_MANAGER_ODS
|
-- Package: ODS.FILE_MANAGER_ODS
|
||||||
-- Version: 2.2.0 -> 2.1.0 (rollback)
|
-- Version: 2.4.0 -> 2.1.0 (rollback)
|
||||||
|
|
||||||
SET ECHO ON
|
SET ECHO ON
|
||||||
SET DEFINE OFF
|
SET DEFINE OFF
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- Purpose: Restore FILE_MANAGER_ODS package specification to v2.1.0
|
-- Purpose: Restore FILE_MANAGER_ODS package specification to v2.1.0
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
-- Package: ODS.FILE_MANAGER_ODS
|
-- Package: ODS.FILE_MANAGER_ODS
|
||||||
-- Version: 2.2.0 -> 2.1.0 (rollback)
|
-- Version: 2.4.0 -> 2.1.0 (rollback)
|
||||||
|
|
||||||
SET ECHO ON
|
SET ECHO ON
|
||||||
SET DEFINE OFF
|
SET DEFINE OFF
|
||||||
|
|||||||
@@ -1,376 +0,0 @@
|
|||||||
# MARS-1057: Batch External Table Creation
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
This MARS package adds batch external table creation capabilities to the FILE_MANAGER and FILE_MANAGER_ODS packages, enabling automatic creation of external table sets (INBOX, ODS, ARCHIVE) based on A_SOURCE_FILE_CONFIG metadata.
|
|
||||||
|
|
||||||
**Jira Issue:** MARS-1057
|
|
||||||
**Package Version:** FILE_MANAGER 3.4.0, FILE_MANAGER_ODS 2.2.0
|
|
||||||
**Author:** Grzegorz Michalski
|
|
||||||
**Date:** 2025-11-27
|
|
||||||
|
|
||||||
## Contents
|
|
||||||
- `install_mars1057.sql` - Master installation script with SPOOL logging
|
|
||||||
- `rollback_mars1057.sql` - Master rollback script
|
|
||||||
- `01_MARS_1057_install_CT_MRDS_FILE_MANAGER_SPEC.sql` - Install FILE_MANAGER package specification
|
|
||||||
- `02_MARS_1057_install_CT_MRDS_FILE_MANAGER_BODY.sql` - Install FILE_MANAGER package body
|
|
||||||
- `03_MARS_1057_install_ODS_FILE_MANAGER_ODS_SPEC.sql` - Install FILE_MANAGER_ODS package specification
|
|
||||||
- `04_MARS_1057_install_ODS_FILE_MANAGER_ODS_BODY.sql` - Install FILE_MANAGER_ODS package body
|
|
||||||
- `91_MARS_1057_rollback_CT_MRDS_FILE_MANAGER_SPEC.sql` - Rollback FILE_MANAGER package specification
|
|
||||||
- `92_MARS_1057_rollback_CT_MRDS_FILE_MANAGER_BODY.sql` - Rollback FILE_MANAGER package body
|
|
||||||
- `93_MARS_1057_rollback_ODS_FILE_MANAGER_ODS_BODY.sql` - Rollback FILE_MANAGER_ODS package body
|
|
||||||
- `94_MARS_1057_rollback_ODS_FILE_MANAGER_ODS_SPEC.sql` - Rollback FILE_MANAGER_ODS package specification
|
|
||||||
- `track_package_versions.sql` - Universal package version tracking
|
|
||||||
- `verify_packages_version.sql` - Universal package verification
|
|
||||||
- `rollback_version/` - FILE_MANAGER v3.3.0, FILE_MANAGER_ODS v2.1.0 (before MARS-1057)
|
|
||||||
- `new_version/` - FILE_MANAGER v3.4.0, FILE_MANAGER_ODS v2.2.0 (after MARS-1057)
|
|
||||||
- `.gitignore` - Git exclusions for temporary files
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
- Oracle Database 23ai
|
|
||||||
- FILE_MANAGER package v3.3.0 installed
|
|
||||||
- FILE_MANAGER_ODS package v2.1.0 installed
|
|
||||||
- ENV_MANAGER package v3.1.0+ with version tracking
|
|
||||||
- ADMIN user access for deployment
|
|
||||||
- ODS schema with necessary privileges
|
|
||||||
|
|
||||||
## New Features
|
|
||||||
|
|
||||||
### 1. CREATE_EXTERNAL_TABLES_SET
|
|
||||||
Creates a complete set of 3 external tables (INBOX, ODS, ARCHIVE) for a single configuration from A_SOURCE_FILE_CONFIG.
|
|
||||||
|
|
||||||
**Signature:**
|
|
||||||
```sql
|
|
||||||
PROCEDURE CREATE_EXTERNAL_TABLES_SET (
|
|
||||||
pSourceFileConfigKey IN NUMBER,
|
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```sql
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET(
|
|
||||||
pSourceFileConfigKey => 123,
|
|
||||||
pRecreate => FALSE
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
```
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Automatic table naming: `{TABLE_ID}_{INBOX|ODS|ARCHIVE}`
|
|
||||||
- Official path patterns compliance
|
|
||||||
- Optional drop and recreate
|
|
||||||
- Full ENV_MANAGER logging
|
|
||||||
- Error handling with detailed messages
|
|
||||||
|
|
||||||
### 2. CREATE_EXTERNAL_TABLES_BATCH
|
|
||||||
Creates external table sets for multiple configurations based on filter criteria.
|
|
||||||
|
|
||||||
**Signature:**
|
|
||||||
```sql
|
|
||||||
PROCEDURE CREATE_EXTERNAL_TABLES_BATCH (
|
|
||||||
pSourceKey IN VARCHAR2 DEFAULT NULL,
|
|
||||||
pSourceFileId IN VARCHAR2 DEFAULT NULL,
|
|
||||||
pTableId IN VARCHAR2 DEFAULT NULL,
|
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Examples:**
|
|
||||||
```sql
|
|
||||||
-- All external tables for C2D source
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
|
||||||
pSourceKey => 'C2D'
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Recreate all external tables
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
|
||||||
pRecreate => TRUE
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Specific table across all sources
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
|
||||||
pTableId => 'A_UC_DISSEM_METADATA_LOADS'
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
```
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Filters only INPUT type files
|
|
||||||
- Continues processing on errors
|
|
||||||
- Returns summary (Total/Processed/Failed)
|
|
||||||
- Comprehensive logging
|
|
||||||
|
|
||||||
### 3. FILE_MANAGER_ODS Wrapper Procedures
|
|
||||||
The ODS.FILE_MANAGER_ODS package now includes DEFINER rights wrappers for the new batch procedures.
|
|
||||||
|
|
||||||
**New Wrappers:**
|
|
||||||
```sql
|
|
||||||
-- Create single external table set via ODS wrapper
|
|
||||||
EXEC ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_SET(
|
|
||||||
pSourceFileConfigKey => 123,
|
|
||||||
pRecreate => FALSE
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Create batch external tables via ODS wrapper
|
|
||||||
EXEC ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_BATCH(
|
|
||||||
pSourceKey => 'C2D',
|
|
||||||
pRecreate => FALSE
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Benefits:**
|
|
||||||
- Objects created in ODS schema regardless of execution user
|
|
||||||
- Same functionality as CT_MRDS.FILE_MANAGER with DEFINER rights
|
|
||||||
- Full logging and error handling
|
|
||||||
- Consistent API with original package
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### Option 1: Master Script (Recommended)
|
|
||||||
```powershell
|
|
||||||
# IMPORTANT: Execute as ADMIN user
|
|
||||||
Get-Content "MARS_Packages/REL03/MARS-1057/install_mars1057.sql" | sql "ADMIN/password@service"
|
|
||||||
|
|
||||||
# Log file created: log/INSTALL_MARS_1057_<PDB>_<timestamp>.log
|
|
||||||
```
|
|
||||||
|
|
||||||
**Installation Steps:**
|
|
||||||
1. Install FILE_MANAGER package specification v3.4.0
|
|
||||||
2. Install FILE_MANAGER package body v3.4.0
|
|
||||||
3. Install FILE_MANAGER_ODS package specification v2.2.0
|
|
||||||
4. Install FILE_MANAGER_ODS package body v2.2.0
|
|
||||||
5. Track versions in A_PACKAGE_VERSION_TRACKING
|
|
||||||
6. Verify all tracked packages for untracked changes
|
|
||||||
|
|
||||||
### Option 2: Individual Scripts
|
|
||||||
```powershell
|
|
||||||
# IMPORTANT: Execute as ADMIN user
|
|
||||||
Get-Content "01_MARS_1057_install_CT_MRDS_FILE_MANAGER_SPEC.sql" | sql "ADMIN/password@service"
|
|
||||||
Get-Content "02_MARS_1057_install_CT_MRDS_FILE_MANAGER_BODY.sql" | sql "ADMIN/password@service"
|
|
||||||
Get-Content "03_MARS_1057_install_ODS_FILE_MANAGER_ODS_SPEC.sql" | sql "ADMIN/password@service"
|
|
||||||
Get-Content "04_MARS_1057_install_ODS_FILE_MANAGER_ODS_BODY.sql" | sql "ADMIN/password@service"
|
|
||||||
Get-Content "track_package_versions.sql" | sql "ADMIN/password@service"
|
|
||||||
Get-Content "verify_packages_version.sql" | sql "ADMIN/password@service"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
```sql
|
|
||||||
-- Check FILE_MANAGER version
|
|
||||||
SELECT CT_MRDS.FILE_MANAGER.GET_VERSION() FROM DUAL;
|
|
||||||
-- Expected: 3.4.0
|
|
||||||
|
|
||||||
-- Check FILE_MANAGER_ODS version
|
|
||||||
SELECT ODS.FILE_MANAGER_ODS.GET_VERSION() FROM DUAL;
|
|
||||||
-- Expected: 2.2.0
|
|
||||||
|
|
||||||
-- Check for errors (ADMIN user checks specific schema)
|
|
||||||
SELECT * FROM ALL_ERRORS
|
|
||||||
WHERE OWNER IN ('CT_MRDS', 'ODS')
|
|
||||||
AND NAME IN ('FILE_MANAGER', 'FILE_MANAGER_ODS');
|
|
||||||
-- Expected: No rows
|
|
||||||
|
|
||||||
-- Verify new FILE_MANAGER procedures exist
|
|
||||||
SELECT procedure_name
|
|
||||||
FROM ALL_PROCEDURES
|
|
||||||
WHERE OWNER = 'CT_MRDS'
|
|
||||||
AND object_name = 'FILE_MANAGER'
|
|
||||||
AND procedure_name IN ('CREATE_EXTERNAL_TABLES_SET', 'CREATE_EXTERNAL_TABLES_BATCH');
|
|
||||||
-- Expected: 2 rows
|
|
||||||
|
|
||||||
-- Verify new FILE_MANAGER_ODS procedures exist
|
|
||||||
SELECT procedure_name
|
|
||||||
FROM ALL_PROCEDURES
|
|
||||||
WHERE OWNER = 'ODS'
|
|
||||||
AND object_name = 'FILE_MANAGER_ODS'
|
|
||||||
AND procedure_name IN ('CREATE_EXTERNAL_TABLES_SET', 'CREATE_EXTERNAL_TABLES_BATCH');
|
|
||||||
-- Expected: 2 rows
|
|
||||||
|
|
||||||
-- Check for untracked changes
|
|
||||||
SELECT CT_MRDS.ENV_MANAGER.CHECK_PACKAGE_CHANGES('CT_MRDS', 'FILE_MANAGER') FROM DUAL;
|
|
||||||
-- Expected: OK: Package CT_MRDS.FILE_MANAGER has not changed.
|
|
||||||
|
|
||||||
SELECT CT_MRDS.ENV_MANAGER.CHECK_PACKAGE_CHANGES('ODS', 'FILE_MANAGER_ODS') FROM DUAL;
|
|
||||||
-- Expected: OK: Package ODS.FILE_MANAGER_ODS has not changed.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Rollback
|
|
||||||
```powershell
|
|
||||||
# IMPORTANT: Execute as ADMIN user
|
|
||||||
Get-Content "MARS_Packages/REL03/MARS-1057/rollback_mars1057.sql" | sql "ADMIN/password@service"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Rollback restores:**
|
|
||||||
- FILE_MANAGER package specification v3.3.0
|
|
||||||
- FILE_MANAGER package body v3.3.0
|
|
||||||
- FILE_MANAGER_ODS package specification v2.1.0
|
|
||||||
- FILE_MANAGER_ODS package body v2.1.0
|
|
||||||
- Removes CREATE_EXTERNAL_TABLES_SET procedures from both packages
|
|
||||||
- Removes CREATE_EXTERNAL_TABLES_BATCH procedures from both packages
|
|
||||||
|
|
||||||
## Expected Changes
|
|
||||||
- **FILE_MANAGER package**: v3.3.0 → v3.4.0
|
|
||||||
- **FILE_MANAGER_ODS package**: v2.1.0 → v2.2.0
|
|
||||||
- **New procedures in FILE_MANAGER**: CREATE_EXTERNAL_TABLES_SET, CREATE_EXTERNAL_TABLES_BATCH
|
|
||||||
- **New procedures in FILE_MANAGER_ODS**: CREATE_EXTERNAL_TABLES_SET, CREATE_EXTERNAL_TABLES_BATCH
|
|
||||||
- **FILE_MANAGER SPEC size**: +3.3 KB (declaration and documentation)
|
|
||||||
- **FILE_MANAGER BODY size**: +8.6 KB (implementation with logging)
|
|
||||||
- **FILE_MANAGER_ODS SPEC size**: +2.8 KB (wrapper declarations)
|
|
||||||
- **FILE_MANAGER_ODS BODY size**: +4.5 KB (wrapper implementations)
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
### Test 1: Create Single Set (CT_MRDS.FILE_MANAGER)
|
|
||||||
```sql
|
|
||||||
BEGIN
|
|
||||||
CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET(
|
|
||||||
pSourceFileConfigKey => 123
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Verify tables created
|
|
||||||
SELECT table_name
|
|
||||||
FROM ALL_TABLES
|
|
||||||
WHERE OWNER = 'ODS'
|
|
||||||
AND (table_name LIKE '%_INBOX'
|
|
||||||
OR table_name LIKE '%_ODS'
|
|
||||||
OR table_name LIKE '%_ARCHIVE');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 2: Create Single Set (ODS.FILE_MANAGER_ODS)
|
|
||||||
```sql
|
|
||||||
BEGIN
|
|
||||||
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_SET(
|
|
||||||
pSourceFileConfigKey => 123,
|
|
||||||
pRecreate => TRUE
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 3: Batch Creation (CT_MRDS.FILE_MANAGER)
|
|
||||||
```sql
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET(
|
|
||||||
pSourceFileConfigKey => 123
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Verify tables created
|
|
||||||
SELECT table_name
|
|
||||||
FROM ALL_TABLES
|
|
||||||
WHERE OWNER = 'ODS'
|
|
||||||
AND table_name LIKE '%_INBOX'
|
|
||||||
OR table_name LIKE '%_ODS'
|
|
||||||
OR table_name LIKE '%_ARCHIVE';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 2: Batch Creation
|
|
||||||
```sql
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
|
||||||
pSourceKey => 'C2D'
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- Check process log for results
|
|
||||||
SELECT *
|
|
||||||
FROM CT_MRDS.A_PROCESS_LOG
|
|
||||||
WHERE LOG_TIMESTAMP > SYSDATE - INTERVAL '1' HOUR
|
|
||||||
AND PROCEDURE_NAME LIKE '%CREATE_EXTERNAL_TABLES%'
|
|
||||||
ORDER BY LOG_TIMESTAMP DESC;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 3: Recreate Existing Tables
|
|
||||||
```sql
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET(
|
|
||||||
pSourceFileConfigKey => 123,
|
|
||||||
pRecreate => TRUE
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage Examples
|
|
||||||
|
|
||||||
### Example 1: Setup All External Tables for New Source
|
|
||||||
```sql
|
|
||||||
-- 1. Add source configuration
|
|
||||||
CALL FILE_MANAGER.ADD_SOURCE('LM', 'Liquidity Management');
|
|
||||||
|
|
||||||
-- 2. Add file configurations
|
|
||||||
CALL FILE_MANAGER.ADD_SOURCE_FILE_CONFIG(
|
|
||||||
pSourceKey => 'LM',
|
|
||||||
pSourceFileType => 'INPUT',
|
|
||||||
pSourceFileId => 'STANDING_FACILITIES',
|
|
||||||
pSourceFileDesc => 'Standing Facilities Data',
|
|
||||||
pSourceFileNamePattern => 'SF_*.csv',
|
|
||||||
pTableId => 'STANDING_FACILITIES',
|
|
||||||
pTemplateTableName => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES',
|
|
||||||
pEncoding => 'UTF8'
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 3. Create all external tables for this source
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
|
||||||
pSourceKey => 'LM'
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 2: Recreate All External Tables
|
|
||||||
```sql
|
|
||||||
-- Useful after bucket URI changes or template table modifications
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
|
||||||
pRecreate => TRUE
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 3: Create Tables for Specific File Type
|
|
||||||
```sql
|
|
||||||
BEGIN
|
|
||||||
FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
|
||||||
pSourceFileId => 'UC_DISSEM'
|
|
||||||
);
|
|
||||||
END;
|
|
||||||
/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Known Issues
|
|
||||||
None
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
- **CT_MRDS.ENV_MANAGER** - Logging and error handling
|
|
||||||
- **ODS.FILE_MANAGER_ODS** - AUTHID DEFINER wrapper for external table creation
|
|
||||||
- **CT_MRDS.A_SOURCE_FILE_CONFIG** - Source file configuration metadata
|
|
||||||
- **CT_ET_TEMPLATES schema** - Template table definitions
|
|
||||||
|
|
||||||
## Related
|
|
||||||
- **MARS-1056** - VARCHAR2 CHAR/BYTE semantics fix
|
|
||||||
- **MARS-1049** - CSV encoding support
|
|
||||||
- **Package Deployment Guide** - Standard deployment procedures
|
|
||||||
- **Tables Setup Guide** - External table configuration guide
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
- All installations must be executed as ADMIN user
|
|
||||||
- Use `ALL_*` views instead of `USER_*` views for verification
|
|
||||||
- Master scripts include SPOOL logging for audit trail
|
|
||||||
- ACCEPT validation prevents accidental execution
|
|
||||||
- Follows official path patterns: INBOX (3-level), ODS (2-level), ARCHIVE (2-level)
|
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- MARS-1057 INSTALL SCRIPT: Batch External Table Creation
|
-- MARS-1057 INSTALL SCRIPT: Batch External Table Creation
|
||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- Purpose: Install FILE_MANAGER v3.4.0 with batch external table creation procedures
|
-- Purpose: Install FILE_MANAGER v3.5.0 with batch external table creation procedures
|
||||||
|
-- and area filter functionality
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
-- Version: 3.4.0
|
-- Version: 3.5.0
|
||||||
|
|
||||||
-- Dynamic spool file generation (using SYS_CONTEXT - no DBA privileges required)
|
-- Dynamic spool file generation (using SYS_CONTEXT - no DBA privileges required)
|
||||||
-- Log files are automatically created in log/ subdirectory
|
-- Log files are automatically created in log/ subdirectory
|
||||||
@@ -29,20 +30,28 @@ SET PAUSE OFF
|
|||||||
-- ALTER SESSION SET CURRENT_SCHEMA = CT_MRDS;
|
-- ALTER SESSION SET CURRENT_SCHEMA = CT_MRDS;
|
||||||
|
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT MARS-1057: Batch External Table Creation
|
PROMPT MARS-1057: Batch External Table Creation + Area Filter
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT This script will install FILE_MANAGER package v3.4.0 with new features:
|
PROMPT This script will install FILE_MANAGER package v3.5.0 with new features:
|
||||||
PROMPT - CREATE_EXTERNAL_TABLES_SET procedure
|
PROMPT - CREATE_EXTERNAL_TABLES_SET procedure
|
||||||
PROMPT - CREATE_EXTERNAL_TABLES_BATCH procedure
|
PROMPT - CREATE_EXTERNAL_TABLES_BATCH procedure
|
||||||
|
PROMPT - pArea parameter for selective table creation (INBOX/ODS/ARCHIVE/ALL)
|
||||||
|
PROMPT - pRestoreGrants parameter for grant preservation during recreate
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT And FILE_MANAGER_ODS package v2.2.0 with wrapper procedures.
|
PROMPT And FILE_MANAGER_ODS package v2.4.0 with wrapper procedures.
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Changes:
|
PROMPT Changes:
|
||||||
PROMPT - FILE_MANAGER package specification (3.3.0 -> 3.4.0)
|
PROMPT - FILE_MANAGER package specification (3.3.0 -> 3.5.0)
|
||||||
PROMPT - FILE_MANAGER package body (3.3.0 -> 3.4.0)
|
PROMPT - FILE_MANAGER package body (3.3.0 -> 3.5.0)
|
||||||
PROMPT - FILE_MANAGER_ODS package specification (2.1.0 -> 2.2.0)
|
PROMPT - FILE_MANAGER_ODS package specification (2.1.0 -> 2.4.0)
|
||||||
PROMPT - FILE_MANAGER_ODS package body (2.1.0 -> 2.2.0)
|
PROMPT - FILE_MANAGER_ODS package body (2.1.0 -> 2.4.0)
|
||||||
|
PROMPT
|
||||||
|
PROMPT New functionality:
|
||||||
|
PROMPT - pArea => 'INBOX' : creates only INBOX table
|
||||||
|
PROMPT - pArea => 'ODS' : creates only ODS table
|
||||||
|
PROMPT - pArea => 'ARCHIVE' : creates only ARCHIVE table
|
||||||
|
PROMPT - pArea => 'ALL' : creates all tables (default)
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Expected Duration: 1-2 minutes
|
PROMPT Expected Duration: 1-2 minutes
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@ -60,25 +69,25 @@ WHENEVER SQLERROR CONTINUE
|
|||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 1: Install FILE_MANAGER Package Specification v3.4.0
|
PROMPT Step 1: Install FILE_MANAGER Package Specification v3.5.0
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@01_MARS_1057_install_CT_MRDS_FILE_MANAGER_SPEC.sql
|
@@01_MARS_1057_install_CT_MRDS_FILE_MANAGER_SPEC.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 2: Install FILE_MANAGER Package Body v3.4.0
|
PROMPT Step 2: Install FILE_MANAGER Package Body v3.5.0
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@02_MARS_1057_install_CT_MRDS_FILE_MANAGER_BODY.sql
|
@@02_MARS_1057_install_CT_MRDS_FILE_MANAGER_BODY.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 3: Install FILE_MANAGER_ODS Package Specification v2.2.0
|
PROMPT Step 3: Install FILE_MANAGER_ODS Package Specification v2.4.0
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@03_MARS_1057_install_ODS_FILE_MANAGER_ODS_SPEC.sql
|
@@03_MARS_1057_install_ODS_FILE_MANAGER_ODS_SPEC.sql
|
||||||
|
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT Step 4: Install FILE_MANAGER_ODS Package Body v2.2.0
|
PROMPT Step 4: Install FILE_MANAGER_ODS Package Body v2.4.0
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
@@04_MARS_1057_install_ODS_FILE_MANAGER_ODS_BODY.sql
|
@@04_MARS_1057_install_ODS_FILE_MANAGER_ODS_BODY.sql
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,66 @@
|
|||||||
create or replace PACKAGE BODY CT_MRDS.FILE_MANAGER
|
create or replace PACKAGE BODY CT_MRDS.FILE_MANAGER
|
||||||
AS
|
AS
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
-- PRIVATE FUNCTION: NORMALIZE_DATE_FORMAT
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Purpose: Normalize Oracle date format strings for use in external tables
|
||||||
|
*
|
||||||
|
* Problem: ISO 8601 formats like 'YYYY-MM-DDTHH24:MI:SS.FF3TZH:TZM' fail because
|
||||||
|
* literal character 'T' must be enclosed in double quotes for Oracle
|
||||||
|
* external table DATE column definitions.
|
||||||
|
*
|
||||||
|
* Solution: Detect unquoted 'T' separator and wrap it in double quotes
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* pDateFormat - Original date format from A_COLUMN_DATE_FORMAT table
|
||||||
|
*
|
||||||
|
* Returns: Normalized format with quoted 'T' if applicable
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* Input: 'YYYY-MM-DDTHH24:MI:SS.FF3TZH:TZM'
|
||||||
|
* Output: 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM'
|
||||||
|
*
|
||||||
|
* Input: 'DD/MM/YYYY HH24:MI:SS' (no T)
|
||||||
|
* Output: 'DD/MM/YYYY HH24:MI:SS' (unchanged)
|
||||||
|
*
|
||||||
|
* Input: 'YYYY-MM-DD"T"HH24:MI:SS' (already quoted)
|
||||||
|
* Output: 'YYYY-MM-DD"T"HH24:MI:SS' (unchanged)
|
||||||
|
*
|
||||||
|
* Author: Grzegorz Michalski
|
||||||
|
* Date: 2025-11-27
|
||||||
|
* Version: 1.0.0 (MARS-1046)
|
||||||
|
*/
|
||||||
|
FUNCTION NORMALIZE_DATE_FORMAT(pDateFormat VARCHAR2) RETURN VARCHAR2 IS
|
||||||
|
vNormalizedFormat VARCHAR2(500);
|
||||||
|
BEGIN
|
||||||
|
-- Return NULL if input is NULL
|
||||||
|
IF pDateFormat IS NULL THEN
|
||||||
|
RETURN NULL;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
vNormalizedFormat := pDateFormat;
|
||||||
|
|
||||||
|
-- Check if 'T' separator exists and is NOT already quoted
|
||||||
|
-- Pattern: [YMD]T[HM] (date component + T + time component)
|
||||||
|
IF INSTR(vNormalizedFormat, '"T"') = 0 AND
|
||||||
|
REGEXP_LIKE(vNormalizedFormat, '[YMD]T[HM]') THEN
|
||||||
|
|
||||||
|
-- Wrap 'T' in double quotes using regex replace
|
||||||
|
-- Pattern matches: (date format char) + T + (time format char)
|
||||||
|
-- Replacement: \1 + "T" + \2
|
||||||
|
vNormalizedFormat := REGEXP_REPLACE(vNormalizedFormat, '([YMD])T([HM])', '\1"T"\2');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN vNormalizedFormat;
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
-- If normalization fails, return original format (safety fallback)
|
||||||
|
RETURN pDateFormat;
|
||||||
|
END NORMALIZE_DATE_FORMAT;
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
FUNCTION GET_SOURCE_FILE_CONFIG(pFileUri IN VARCHAR2 DEFAULT NULL
|
FUNCTION GET_SOURCE_FILE_CONFIG(pFileUri IN VARCHAR2 DEFAULT NULL
|
||||||
@@ -1254,8 +1314,17 @@ AS
|
|||||||
-- Note: field_list uses CHAR() for CSV field definitions - this is correct behavior
|
-- Note: field_list uses CHAR() for CSV field definitions - this is correct behavior
|
||||||
pFieldList := pFieldList ||
|
pFieldList := pFieldList ||
|
||||||
CASE
|
CASE
|
||||||
WHEN REGEXP_SUBSTR(rec.data_type, '^[A-Z]+') IN ('DATE', 'TIMESTAMP') THEN
|
WHEN rec.data_type = 'DATE' THEN
|
||||||
rec.quoted_column_name || ' DATE ' || CHR(39) || GET_DATE_FORMAT(pTemplateTableName => pTemplateTableName, pColumnName => rec.column_name) || CHR(39)
|
-- MARS-1046: DATE format - wrap with NORMALIZE_DATE_FORMAT to fix ISO 8601 'T' separator
|
||||||
|
rec.quoted_column_name || ' DATE ' || CHR(39) || NORMALIZE_DATE_FORMAT(GET_DATE_FORMAT(pTemplateTableName => pTemplateTableName, pColumnName => rec.column_name)) || CHR(39)
|
||||||
|
WHEN rec.data_type LIKE 'TIMESTAMP%WITH TIME ZONE' THEN
|
||||||
|
-- MARS-1046: TIMESTAMP WITH TIME ZONE format for ISO 8601 with fractional seconds and timezone
|
||||||
|
-- Syntax: column_name CHAR(length) DATE_FORMAT TIMESTAMP WITH TIME ZONE MASK "format"
|
||||||
|
-- Use fixed length of 50 for ISO 8601 format (e.g., "2012-03-02T14:16:23.798+01:00" = 29 chars)
|
||||||
|
rec.quoted_column_name || ' CHAR(50) DATE_FORMAT TIMESTAMP WITH TIME ZONE MASK ' || CHR(39) || NORMALIZE_DATE_FORMAT(GET_DATE_FORMAT(pTemplateTableName => pTemplateTableName, pColumnName => rec.column_name)) || CHR(39)
|
||||||
|
WHEN REGEXP_SUBSTR(rec.data_type, '^[A-Z]+') = 'TIMESTAMP' THEN
|
||||||
|
-- Other TIMESTAMP types (without timezone)
|
||||||
|
rec.quoted_column_name || ' TIMESTAMP ' || CHR(39) || NORMALIZE_DATE_FORMAT(GET_DATE_FORMAT(pTemplateTableName => pTemplateTableName, pColumnName => rec.column_name)) || CHR(39)
|
||||||
WHEN rec.data_type IN ('CHAR', 'NCHAR', 'VARCHAR2', 'NVARCHAR2') THEN
|
WHEN rec.data_type IN ('CHAR', 'NCHAR', 'VARCHAR2', 'NVARCHAR2') THEN
|
||||||
-- For CSV field definitions, use data_length for CHAR() specification
|
-- For CSV field definitions, use data_length for CHAR() specification
|
||||||
rec.quoted_column_name || ' CHAR(' || rec.data_length || ')'
|
rec.quoted_column_name || ' CHAR(' || rec.data_length || ')'
|
||||||
@@ -1899,9 +1968,23 @@ AS
|
|||||||
|
|
||||||
PROCEDURE CREATE_EXTERNAL_TABLES_SET (
|
PROCEDURE CREATE_EXTERNAL_TABLES_SET (
|
||||||
pSourceFileConfigKey IN NUMBER,
|
pSourceFileConfigKey IN NUMBER,
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
pRecreate IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pRestoreGrants IN BOOLEAN DEFAULT TRUE,
|
||||||
|
pArea IN VARCHAR2 DEFAULT 'ALL'
|
||||||
)
|
)
|
||||||
IS
|
IS
|
||||||
|
-- Type for storing grant information
|
||||||
|
TYPE tGrantRecord IS RECORD (
|
||||||
|
grantee VARCHAR2(128),
|
||||||
|
privilege VARCHAR2(40),
|
||||||
|
grantable VARCHAR2(3)
|
||||||
|
);
|
||||||
|
TYPE tGrantList IS TABLE OF tGrantRecord;
|
||||||
|
|
||||||
|
vInboxGrants tGrantList;
|
||||||
|
vOdsGrants tGrantList;
|
||||||
|
vArchiveGrants tGrantList;
|
||||||
|
|
||||||
vSourceKey VARCHAR2(50);
|
vSourceKey VARCHAR2(50);
|
||||||
vSourceFileId VARCHAR2(100);
|
vSourceFileId VARCHAR2(100);
|
||||||
vTableId VARCHAR2(100);
|
vTableId VARCHAR2(100);
|
||||||
@@ -1917,28 +2000,124 @@ AS
|
|||||||
vOdsPrefix VARCHAR2(500);
|
vOdsPrefix VARCHAR2(500);
|
||||||
vArchivePrefix VARCHAR2(500);
|
vArchivePrefix VARCHAR2(500);
|
||||||
|
|
||||||
vTableExists NUMBER;
|
|
||||||
vParameters VARCHAR2(4000);
|
vParameters VARCHAR2(4000);
|
||||||
|
vAreaUpper VARCHAR2(20);
|
||||||
|
|
||||||
|
-- Nested procedure to save table grants before DROP
|
||||||
|
PROCEDURE SAVE_GRANTS(pTableName VARCHAR2, pGrantList OUT tGrantList) IS
|
||||||
|
BEGIN
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Saving grants for table: ' || pTableName, 'DEBUG');
|
||||||
|
|
||||||
|
SELECT grantee, privilege, grantable
|
||||||
|
BULK COLLECT INTO pGrantList
|
||||||
|
FROM ALL_TAB_PRIVS
|
||||||
|
WHERE table_schema = SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA')
|
||||||
|
AND table_name = pTableName
|
||||||
|
AND grantee NOT IN ('SYS', 'SYSTEM', 'PUBLIC') -- Exclude system accounts
|
||||||
|
ORDER BY grantee, privilege;
|
||||||
|
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
|
'Saved ' || pGrantList.COUNT || ' grants for table: ' || SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') || '.' || pTableName,
|
||||||
|
'INFO'
|
||||||
|
);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN NO_DATA_FOUND THEN
|
||||||
|
pGrantList := tGrantList(); -- Empty list
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('No grants found for table: ' || pTableName, 'INFO');
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
|
'Warning: Could not save grants for ' || pTableName || ': ' || SQLERRM,
|
||||||
|
'WARNING'
|
||||||
|
);
|
||||||
|
pGrantList := tGrantList(); -- Empty list on error
|
||||||
|
END SAVE_GRANTS;
|
||||||
|
|
||||||
|
-- Nested procedure to restore table grants after CREATE
|
||||||
|
PROCEDURE RESTORE_GRANTS(pTableName VARCHAR2, pGrantList tGrantList) IS
|
||||||
|
vGrantSQL VARCHAR2(500);
|
||||||
|
vGrantCount NUMBER := 0;
|
||||||
|
vFailCount NUMBER := 0;
|
||||||
|
BEGIN
|
||||||
|
IF pGrantList IS NULL OR pGrantList.COUNT = 0 THEN
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
|
'No grants to restore for table: ' || pTableName,
|
||||||
|
'INFO'
|
||||||
|
);
|
||||||
|
RETURN;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
|
'Restoring ' || pGrantList.COUNT || ' grants for table: ' || pTableName,
|
||||||
|
'DEBUG'
|
||||||
|
);
|
||||||
|
|
||||||
|
FOR i IN 1..pGrantList.COUNT LOOP
|
||||||
|
BEGIN
|
||||||
|
vGrantSQL := 'GRANT ' || pGrantList(i).privilege ||
|
||||||
|
' ON ' || SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') || '.' || pTableName ||
|
||||||
|
' TO ' || pGrantList(i).grantee;
|
||||||
|
|
||||||
|
IF pGrantList(i).grantable = 'YES' THEN
|
||||||
|
vGrantSQL := vGrantSQL || ' WITH GRANT OPTION';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXECUTE IMMEDIATE vGrantSQL;
|
||||||
|
vGrantCount := vGrantCount + 1;
|
||||||
|
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
|
'Restored grant: ' || pGrantList(i).privilege ||
|
||||||
|
' TO ' || pGrantList(i).grantee ||
|
||||||
|
CASE WHEN pGrantList(i).grantable = 'YES' THEN ' WITH GRANT OPTION' ELSE '' END,
|
||||||
|
'DEBUG'
|
||||||
|
);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
vFailCount := vFailCount + 1;
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
|
'Warning: Could not restore grant (' || pGrantList(i).privilege ||
|
||||||
|
' TO ' || pGrantList(i).grantee || ') on ' || pTableName || ': ' || SQLERRM,
|
||||||
|
'WARNING'
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
|
'Restored ' || vGrantCount || ' of ' || pGrantList.COUNT ||
|
||||||
|
' grants for table: ' || SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') || '.' || pTableName ||
|
||||||
|
CASE WHEN vFailCount > 0 THEN ' (' || vFailCount || ' failed)' ELSE '' END,
|
||||||
|
'INFO'
|
||||||
|
);
|
||||||
|
END RESTORE_GRANTS;
|
||||||
|
|
||||||
PROCEDURE DROP_IF_EXISTS(pTableName VARCHAR2) IS
|
PROCEDURE DROP_IF_EXISTS(pTableName VARCHAR2) IS
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT COUNT(*) INTO vTableExists
|
ENV_MANAGER.LOG_PROCESS_EVENT('Attempting to drop table: ' || pTableName, 'DEBUG');
|
||||||
FROM ALL_TABLES
|
EXECUTE IMMEDIATE 'DROP TABLE ' || SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') || '.' || pTableName;
|
||||||
WHERE OWNER = 'ODS' AND TABLE_NAME = pTableName;
|
ENV_MANAGER.LOG_PROCESS_EVENT('Table dropped successfully: ' || pTableName, 'INFO');
|
||||||
|
|
||||||
IF vTableExists > 0 THEN
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Dropping existing table: ' || pTableName, 'INFO');
|
|
||||||
EXECUTE IMMEDIATE 'DROP TABLE ODS.' || pTableName;
|
|
||||||
END IF;
|
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
|
IF SQLCODE = -942 THEN -- ORA-00942: table or view does not exist
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Table does not exist, skipping drop: ' || pTableName, 'INFO');
|
||||||
|
ELSE
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Error dropping table ' || pTableName || ': ' || SQLERRM, 'WARNING');
|
ENV_MANAGER.LOG_PROCESS_EVENT('Error dropping table ' || pTableName || ': ' || SQLERRM, 'WARNING');
|
||||||
|
RAISE; -- Re-raise if not "table not exists" error
|
||||||
|
END IF;
|
||||||
END DROP_IF_EXISTS;
|
END DROP_IF_EXISTS;
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
|
-- Validate and normalize pArea parameter
|
||||||
|
vAreaUpper := UPPER(TRIM(pArea));
|
||||||
|
|
||||||
|
IF vAreaUpper NOT IN ('INBOX', 'ODS', 'ARCHIVE', 'ALL') THEN
|
||||||
|
vgMsgTmp := 'Invalid pArea parameter: ''' || pArea || '''. Must be one of: INBOX, ODS, ARCHIVE, ALL';
|
||||||
|
RAISE_APPLICATION_ERROR(-20010, vgMsgTmp);
|
||||||
|
END IF;
|
||||||
|
|
||||||
vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
||||||
'pSourceFileConfigKey => ' || NVL(TO_CHAR(pSourceFileConfigKey), 'NULL'),
|
'pSourceFileConfigKey => ' || NVL(TO_CHAR(pSourceFileConfigKey), 'NULL'),
|
||||||
'pRecreate => ' || CASE WHEN pRecreate THEN 'TRUE' ELSE 'FALSE' END
|
'pRecreate => ' || CASE WHEN pRecreate THEN 'TRUE' ELSE 'FALSE' END,
|
||||||
|
'pRestoreGrants => ' || CASE WHEN pRestoreGrants THEN 'TRUE' ELSE 'FALSE' END,
|
||||||
|
'pArea => ''' || vAreaUpper || ''''
|
||||||
));
|
));
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Start CREATE_EXTERNAL_TABLES_SET', 'INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Start CREATE_EXTERNAL_TABLES_SET', 'INFO', vParameters);
|
||||||
|
|
||||||
@@ -1971,18 +2150,46 @@ AS
|
|||||||
vArchivePrefix := 'ARCHIVE/' || vSourceKey || '/' || vTableId;
|
vArchivePrefix := 'ARCHIVE/' || vSourceKey || '/' || vTableId;
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT(
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
'Creating external tables for: ' || vSourceKey || '/' || vSourceFileId || '/' || vTableId,
|
'Creating external tables for: ' || vSourceKey || '/' || vSourceFileId || '/' || vTableId ||
|
||||||
|
' (Area: ' || vAreaUpper || ')',
|
||||||
'INFO'
|
'INFO'
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 4. DROP existing tables if pRecreate = TRUE
|
-- 4. DROP existing tables if pRecreate = TRUE
|
||||||
IF pRecreate THEN
|
IF pRecreate THEN
|
||||||
DROP_IF_EXISTS(vInboxTableName);
|
-- Save grants before dropping tables (if pRestoreGrants = TRUE)
|
||||||
DROP_IF_EXISTS(vOdsTableName);
|
IF pRestoreGrants THEN
|
||||||
DROP_IF_EXISTS(vArchiveTableName);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Saving grants before dropping tables...', 'INFO');
|
||||||
|
|
||||||
|
IF vAreaUpper IN ('INBOX', 'ALL') THEN
|
||||||
|
SAVE_GRANTS(vInboxTableName, vInboxGrants);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- 5. Create INBOX external table
|
IF vAreaUpper IN ('ODS', 'ALL') THEN
|
||||||
|
SAVE_GRANTS(vOdsTableName, vOdsGrants);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vAreaUpper IN ('ARCHIVE', 'ALL') THEN
|
||||||
|
SAVE_GRANTS(vArchiveTableName, vArchiveGrants);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Drop existing tables based on pArea
|
||||||
|
IF vAreaUpper IN ('INBOX', 'ALL') THEN
|
||||||
|
DROP_IF_EXISTS(vInboxTableName);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vAreaUpper IN ('ODS', 'ALL') THEN
|
||||||
|
DROP_IF_EXISTS(vOdsTableName);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vAreaUpper IN ('ARCHIVE', 'ALL') THEN
|
||||||
|
DROP_IF_EXISTS(vArchiveTableName);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- 5. Create INBOX external table (if requested)
|
||||||
|
IF vAreaUpper IN ('INBOX', 'ALL') THEN
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Creating INBOX external table: ' || vInboxTableName, 'INFO');
|
ENV_MANAGER.LOG_PROCESS_EVENT('Creating INBOX external table: ' || vInboxTableName, 'INFO');
|
||||||
CREATE_EXTERNAL_TABLE(
|
CREATE_EXTERNAL_TABLE(
|
||||||
pTableName => vInboxTableName,
|
pTableName => vInboxTableName,
|
||||||
@@ -1992,8 +2199,10 @@ AS
|
|||||||
pDelimiter => vDelimiter,
|
pDelimiter => vDelimiter,
|
||||||
pEncoding => vEncoding
|
pEncoding => vEncoding
|
||||||
);
|
);
|
||||||
|
END IF;
|
||||||
|
|
||||||
-- 6. Create ODS external table
|
-- 6. Create ODS external table (if requested)
|
||||||
|
IF vAreaUpper IN ('ODS', 'ALL') THEN
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Creating ODS external table: ' || vOdsTableName, 'INFO');
|
ENV_MANAGER.LOG_PROCESS_EVENT('Creating ODS external table: ' || vOdsTableName, 'INFO');
|
||||||
CREATE_EXTERNAL_TABLE(
|
CREATE_EXTERNAL_TABLE(
|
||||||
pTableName => vOdsTableName,
|
pTableName => vOdsTableName,
|
||||||
@@ -2003,8 +2212,10 @@ AS
|
|||||||
pDelimiter => vDelimiter,
|
pDelimiter => vDelimiter,
|
||||||
pEncoding => vEncoding
|
pEncoding => vEncoding
|
||||||
);
|
);
|
||||||
|
END IF;
|
||||||
|
|
||||||
-- 7. Create ARCHIVE external table
|
-- 7. Create ARCHIVE external table (if requested)
|
||||||
|
IF vAreaUpper IN ('ARCHIVE', 'ALL') THEN
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Creating ARCHIVE external table: ' || vArchiveTableName, 'INFO');
|
ENV_MANAGER.LOG_PROCESS_EVENT('Creating ARCHIVE external table: ' || vArchiveTableName, 'INFO');
|
||||||
CREATE_EXTERNAL_TABLE(
|
CREATE_EXTERNAL_TABLE(
|
||||||
pTableName => vArchiveTableName,
|
pTableName => vArchiveTableName,
|
||||||
@@ -2014,9 +2225,28 @@ AS
|
|||||||
pDelimiter => vDelimiter,
|
pDelimiter => vDelimiter,
|
||||||
pEncoding => vEncoding
|
pEncoding => vEncoding
|
||||||
);
|
);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- 8. Restore grants after creating tables (if pRecreate = TRUE and pRestoreGrants = TRUE)
|
||||||
|
IF pRecreate AND pRestoreGrants THEN
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Restoring grants after creating tables...', 'INFO');
|
||||||
|
|
||||||
|
IF vAreaUpper IN ('INBOX', 'ALL') THEN
|
||||||
|
RESTORE_GRANTS(vInboxTableName, vInboxGrants);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vAreaUpper IN ('ODS', 'ALL') THEN
|
||||||
|
RESTORE_GRANTS(vOdsTableName, vOdsGrants);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vAreaUpper IN ('ARCHIVE', 'ALL') THEN
|
||||||
|
RESTORE_GRANTS(vArchiveTableName, vArchiveGrants);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT(
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
'End CREATE_EXTERNAL_TABLES_SET - Successfully created all 3 external tables for config: ' || pSourceFileConfigKey,
|
'End CREATE_EXTERNAL_TABLES_SET - Successfully created external tables for config: ' ||
|
||||||
|
pSourceFileConfigKey || ' (Area: ' || vAreaUpper || ')',
|
||||||
'INFO',
|
'INFO',
|
||||||
vParameters
|
vParameters
|
||||||
);
|
);
|
||||||
@@ -2034,19 +2264,32 @@ AS
|
|||||||
pSourceKey IN VARCHAR2 DEFAULT NULL,
|
pSourceKey IN VARCHAR2 DEFAULT NULL,
|
||||||
pSourceFileId IN VARCHAR2 DEFAULT NULL,
|
pSourceFileId IN VARCHAR2 DEFAULT NULL,
|
||||||
pTableId IN VARCHAR2 DEFAULT NULL,
|
pTableId IN VARCHAR2 DEFAULT NULL,
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
pRecreate IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pRestoreGrants IN BOOLEAN DEFAULT TRUE,
|
||||||
|
pArea IN VARCHAR2 DEFAULT 'ALL'
|
||||||
)
|
)
|
||||||
IS
|
IS
|
||||||
vCount NUMBER := 0;
|
vCount NUMBER := 0;
|
||||||
vProcessed NUMBER := 0;
|
vProcessed NUMBER := 0;
|
||||||
vFailed NUMBER := 0;
|
vFailed NUMBER := 0;
|
||||||
vParameters VARCHAR2(4000);
|
vParameters VARCHAR2(4000);
|
||||||
|
vAreaUpper VARCHAR2(20);
|
||||||
BEGIN
|
BEGIN
|
||||||
|
-- Validate and normalize pArea parameter
|
||||||
|
vAreaUpper := UPPER(TRIM(pArea));
|
||||||
|
|
||||||
|
IF vAreaUpper NOT IN ('INBOX', 'ODS', 'ARCHIVE', 'ALL') THEN
|
||||||
|
vgMsgTmp := 'Invalid pArea parameter: ''' || pArea || '''. Must be one of: INBOX, ODS, ARCHIVE, ALL';
|
||||||
|
RAISE_APPLICATION_ERROR(-20010, vgMsgTmp);
|
||||||
|
END IF;
|
||||||
|
|
||||||
vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST(
|
||||||
'pSourceKey => ''' || NVL(pSourceKey, 'NULL') || '''',
|
'pSourceKey => ''' || NVL(pSourceKey, 'NULL') || '''',
|
||||||
'pSourceFileId => ''' || NVL(pSourceFileId, 'NULL') || '''',
|
'pSourceFileId => ''' || NVL(pSourceFileId, 'NULL') || '''',
|
||||||
'pTableId => ''' || NVL(pTableId, 'NULL') || '''',
|
'pTableId => ''' || NVL(pTableId, 'NULL') || '''',
|
||||||
'pRecreate => ' || CASE WHEN pRecreate THEN 'TRUE' ELSE 'FALSE' END
|
'pRecreate => ' || CASE WHEN pRecreate THEN 'TRUE' ELSE 'FALSE' END,
|
||||||
|
'pRestoreGrants => ' || CASE WHEN pRestoreGrants THEN 'TRUE' ELSE 'FALSE' END,
|
||||||
|
'pArea => ''' || vAreaUpper || ''''
|
||||||
));
|
));
|
||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Start CREATE_EXTERNAL_TABLES_BATCH', 'INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Start CREATE_EXTERNAL_TABLES_BATCH', 'INFO', vParameters);
|
||||||
@@ -2066,14 +2309,16 @@ AS
|
|||||||
BEGIN
|
BEGIN
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT(
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
'Creating external tables set for: ' || rec.A_SOURCE_KEY || '/' ||
|
'Creating external tables set for: ' || rec.A_SOURCE_KEY || '/' ||
|
||||||
rec.SOURCE_FILE_ID || '/' || rec.TABLE_ID,
|
rec.SOURCE_FILE_ID || '/' || rec.TABLE_ID || ' (Area: ' || vAreaUpper || ')',
|
||||||
'INFO'
|
'INFO'
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Call procedure to create set of 3 tables
|
-- Call procedure to create set of tables (based on pArea)
|
||||||
CREATE_EXTERNAL_TABLES_SET(
|
CREATE_EXTERNAL_TABLES_SET(
|
||||||
pSourceFileConfigKey => rec.A_SOURCE_FILE_CONFIG_KEY,
|
pSourceFileConfigKey => rec.A_SOURCE_FILE_CONFIG_KEY,
|
||||||
pRecreate => pRecreate
|
pRecreate => pRecreate,
|
||||||
|
pRestoreGrants => pRestoreGrants,
|
||||||
|
pArea => vAreaUpper
|
||||||
);
|
);
|
||||||
|
|
||||||
vProcessed := vProcessed + 1;
|
vProcessed := vProcessed + 1;
|
||||||
@@ -2092,7 +2337,7 @@ AS
|
|||||||
|
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT(
|
ENV_MANAGER.LOG_PROCESS_EVENT(
|
||||||
'End CREATE_EXTERNAL_TABLES_BATCH - Total: ' || vCount ||
|
'End CREATE_EXTERNAL_TABLES_BATCH - Total: ' || vCount ||
|
||||||
', Processed: ' || vProcessed || ', Failed: ' || vFailed,
|
', Processed: ' || vProcessed || ', Failed: ' || vFailed || ' (Area: ' || vAreaUpper || ')',
|
||||||
'INFO',
|
'INFO',
|
||||||
vParameters
|
vParameters
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -17,13 +17,15 @@ AS
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
||||||
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.4.0';
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.5.0';
|
||||||
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-11-27 14:00:00';
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-18 16: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.5.0 (2026-02-18): MARS-1057 - Added pArea parameter for selective table creation (INBOX/ODS/ARCHIVE/ALL)' || CHR(13)||CHR(10) ||
|
||||||
'3.4.0 (2025-11-27): MARS-1057 - Added CREATE_EXTERNAL_TABLES_SET and CREATE_EXTERNAL_TABLES_BATCH procedures for batch external table creation' || CHR(13)||CHR(10) ||
|
'3.4.0 (2025-11-27): MARS-1057 - Added CREATE_EXTERNAL_TABLES_SET and CREATE_EXTERNAL_TABLES_BATCH procedures for batch external table creation' || 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.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.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.2.0 (2025-10-22): Added package versioning system using centralized ENV_MANAGER functions' || CHR(13)||CHR(10) ||
|
||||||
@@ -601,48 +603,72 @@ AS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @name CREATE_EXTERNAL_TABLES_SET
|
* @name CREATE_EXTERNAL_TABLES_SET
|
||||||
* @desc Creates a complete set of 3 external tables (INBOX, ODS, ARCHIVE) for a single configuration
|
* @desc Creates a complete set of external tables for a single configuration from A_SOURCE_FILE_CONFIG table.
|
||||||
* from A_SOURCE_FILE_CONFIG table. Automatically generates table names and paths following
|
* Automatically generates table names and paths following official path patterns.
|
||||||
* official path patterns. Optionally drops and recreates existing tables.
|
* Optionally drops and recreates existing tables. If pRestoreGrants is TRUE, saves and restores table grants.
|
||||||
|
* The pArea parameter allows selective table creation.
|
||||||
* @param pSourceFileConfigKey - Primary key from A_SOURCE_FILE_CONFIG table
|
* @param pSourceFileConfigKey - Primary key from A_SOURCE_FILE_CONFIG table
|
||||||
* @param pRecreate - If TRUE, drops existing tables before creating new ones; if FALSE, fails if tables exist
|
* @param pRecreate - If TRUE, drops existing tables before creating new ones; if FALSE, fails if tables exist
|
||||||
* @example BEGIN
|
* @param pRestoreGrants - If TRUE, saves grants before DROP and restores after CREATE (only when pRecreate=TRUE)
|
||||||
|
* Uses DBA_TAB_PRIVS - requires SELECT ANY DICTIONARY or SELECT ON DBA_TAB_PRIVS privilege
|
||||||
|
* @param pArea - Specifies which tables to create: 'INBOX', 'ODS', 'ARCHIVE', or 'ALL' (default)
|
||||||
|
* 'INBOX' - creates only INBOX table
|
||||||
|
* 'ODS' - creates only ODS table
|
||||||
|
* 'ARCHIVE' - creates only ARCHIVE table
|
||||||
|
* 'ALL' - creates all three tables (default)
|
||||||
|
* @example -- Create only INBOX table
|
||||||
|
* BEGIN
|
||||||
* FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET(
|
* FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET(
|
||||||
* pSourceFileConfigKey => 123,
|
* pSourceFileConfigKey => 123,
|
||||||
* pRecreate => FALSE
|
* pArea => 'INBOX'
|
||||||
* );
|
* );
|
||||||
* END;
|
* END;
|
||||||
* @ex_rslt Creates three external tables in ODS schema:
|
*
|
||||||
* - C2D_A_UC_DISSEM_METADATA_LOADS_INBOX
|
* -- Create all tables with grant preservation
|
||||||
* - C2D_A_UC_DISSEM_METADATA_LOADS_ODS
|
* BEGIN
|
||||||
* - C2D_A_UC_DISSEM_METADATA_LOADS_ARCHIVE
|
* FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET(
|
||||||
|
* pSourceFileConfigKey => 123,
|
||||||
|
* pRecreate => TRUE,
|
||||||
|
* pRestoreGrants => TRUE,
|
||||||
|
* pArea => 'ALL'
|
||||||
|
* );
|
||||||
|
* END;
|
||||||
|
* @ex_rslt Creates external table(s) in ODS schema based on pArea parameter
|
||||||
**/
|
**/
|
||||||
PROCEDURE CREATE_EXTERNAL_TABLES_SET (
|
PROCEDURE CREATE_EXTERNAL_TABLES_SET (
|
||||||
pSourceFileConfigKey IN NUMBER,
|
pSourceFileConfigKey IN NUMBER,
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
pRecreate IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pRestoreGrants IN BOOLEAN DEFAULT TRUE,
|
||||||
|
pArea IN VARCHAR2 DEFAULT 'ALL'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name CREATE_EXTERNAL_TABLES_BATCH
|
* @name CREATE_EXTERNAL_TABLES_BATCH
|
||||||
* @desc Creates external table sets for multiple configurations based on filter criteria.
|
* @desc Creates external table sets for multiple configurations based on filter criteria.
|
||||||
* Processes only INPUT type files from A_SOURCE_FILE_CONFIG. Creates 3 tables per configuration
|
* Processes only INPUT type files from A_SOURCE_FILE_CONFIG. Creates tables based on pArea parameter
|
||||||
* (INBOX, ODS, ARCHIVE). Continues processing even if individual sets fail.
|
* (INBOX, ODS, ARCHIVE, or ALL). Continues processing even if individual sets fail.
|
||||||
|
* If pRestoreGrants is TRUE, saves and restores table grants during recreate operations.
|
||||||
* @param pSourceKey - Filter by A_SOURCE_KEY (NULL = all sources)
|
* @param pSourceKey - Filter by A_SOURCE_KEY (NULL = all sources)
|
||||||
* @param pSourceFileId - Filter by SOURCE_FILE_ID (NULL = all file types)
|
* @param pSourceFileId - Filter by SOURCE_FILE_ID (NULL = all file types)
|
||||||
* @param pTableId - Filter by TABLE_ID (NULL = all tables)
|
* @param pTableId - Filter by TABLE_ID (NULL = all tables)
|
||||||
* @param pRecreate - If TRUE, drops and recreates existing tables; if FALSE, skips if tables exist
|
* @param pRecreate - If TRUE, drops and recreates existing tables; if FALSE, skips if tables exist
|
||||||
* @example -- Create all external tables for C2D source
|
* @param pRestoreGrants - If TRUE, saves grants before DROP and restores after CREATE (only when pRecreate=TRUE)
|
||||||
|
* Uses DBA_TAB_PRIVS - requires SELECT ANY DICTIONARY or SELECT ON DBA_TAB_PRIVS privilege
|
||||||
|
* @param pArea - Specifies which tables to create: 'INBOX', 'ODS', 'ARCHIVE', or 'ALL' (default)
|
||||||
|
* @example -- Create only INBOX tables for C2D source
|
||||||
* BEGIN
|
* BEGIN
|
||||||
* FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
* FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
||||||
* pSourceKey => 'C2D',
|
* pSourceKey => 'C2D',
|
||||||
* pRecreate => FALSE
|
* pArea => 'INBOX'
|
||||||
* );
|
* );
|
||||||
* END;
|
* END;
|
||||||
*
|
*
|
||||||
* -- Recreate all external tables for all sources
|
* -- Create all external tables for all sources with grant preservation
|
||||||
* BEGIN
|
* BEGIN
|
||||||
* FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
* FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH(
|
||||||
* pRecreate => TRUE
|
* pRecreate => TRUE,
|
||||||
|
* pRestoreGrants => TRUE,
|
||||||
|
* pArea => 'ALL'
|
||||||
* );
|
* );
|
||||||
* END;
|
* END;
|
||||||
* @ex_rslt Returns summary: Total: 10, Processed: 9, Failed: 1
|
* @ex_rslt Returns summary: Total: 10, Processed: 9, Failed: 1
|
||||||
@@ -651,7 +677,9 @@ AS
|
|||||||
pSourceKey IN VARCHAR2 DEFAULT NULL,
|
pSourceKey IN VARCHAR2 DEFAULT NULL,
|
||||||
pSourceFileId IN VARCHAR2 DEFAULT NULL,
|
pSourceFileId IN VARCHAR2 DEFAULT NULL,
|
||||||
pTableId IN VARCHAR2 DEFAULT NULL,
|
pTableId IN VARCHAR2 DEFAULT NULL,
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
pRecreate IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pRestoreGrants IN BOOLEAN DEFAULT TRUE,
|
||||||
|
pArea IN VARCHAR2 DEFAULT 'ALL'
|
||||||
);
|
);
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -63,20 +63,26 @@ AS
|
|||||||
*/
|
*/
|
||||||
PROCEDURE CREATE_EXTERNAL_TABLES_SET (
|
PROCEDURE CREATE_EXTERNAL_TABLES_SET (
|
||||||
pSourceFileConfigKey IN NUMBER,
|
pSourceFileConfigKey IN NUMBER,
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
pRecreate IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pRestoreGrants IN BOOLEAN DEFAULT TRUE,
|
||||||
|
pArea IN VARCHAR2 DEFAULT 'ALL'
|
||||||
)
|
)
|
||||||
IS
|
IS
|
||||||
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
vRecreateStr VARCHAR2(10);
|
vRecreateStr VARCHAR2(10);
|
||||||
|
vRestoreGrantsStr VARCHAR2(10);
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Convert BOOLEAN to VARCHAR2 for logging
|
-- Convert BOOLEAN to VARCHAR2 for logging
|
||||||
vRecreateStr := CASE WHEN pRecreate THEN 'TRUE' ELSE 'FALSE' END;
|
vRecreateStr := CASE WHEN pRecreate THEN 'TRUE' ELSE 'FALSE' END;
|
||||||
|
vRestoreGrantsStr := CASE WHEN pRestoreGrants THEN 'TRUE' ELSE 'FALSE' END;
|
||||||
|
|
||||||
-- Log the start of the procedure
|
-- Log the start of the procedure
|
||||||
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(
|
||||||
SYS.ODCIVARCHAR2LIST(
|
SYS.ODCIVARCHAR2LIST(
|
||||||
'pSourceFileConfigKey => ' || pSourceFileConfigKey,
|
'pSourceFileConfigKey => ' || pSourceFileConfigKey,
|
||||||
'pRecreate => ' || vRecreateStr
|
'pRecreate => ' || vRecreateStr,
|
||||||
|
'pRestoreGrants => ' || vRestoreGrantsStr,
|
||||||
|
'pArea => ''' || pArea || ''''
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -87,7 +93,9 @@ AS
|
|||||||
-- and ODS wrapper simply delegates execution with DEFINER rights
|
-- and ODS wrapper simply delegates execution with DEFINER rights
|
||||||
CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET(
|
CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET(
|
||||||
pSourceFileConfigKey => pSourceFileConfigKey,
|
pSourceFileConfigKey => pSourceFileConfigKey,
|
||||||
pRecreate => pRecreate
|
pRecreate => pRecreate,
|
||||||
|
pRestoreGrants => pRestoreGrants,
|
||||||
|
pArea => pArea
|
||||||
);
|
);
|
||||||
|
|
||||||
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_SET', 'INFO', vParameters);
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_SET', 'INFO', vParameters);
|
||||||
@@ -111,14 +119,18 @@ AS
|
|||||||
pSourceKey IN VARCHAR2 DEFAULT NULL,
|
pSourceKey IN VARCHAR2 DEFAULT NULL,
|
||||||
pSourceFileId IN VARCHAR2 DEFAULT NULL,
|
pSourceFileId IN VARCHAR2 DEFAULT NULL,
|
||||||
pTableId IN VARCHAR2 DEFAULT NULL,
|
pTableId IN VARCHAR2 DEFAULT NULL,
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
pRecreate IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pRestoreGrants IN BOOLEAN DEFAULT TRUE,
|
||||||
|
pArea IN VARCHAR2 DEFAULT 'ALL'
|
||||||
)
|
)
|
||||||
IS
|
IS
|
||||||
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE;
|
||||||
vRecreateStr VARCHAR2(10);
|
vRecreateStr VARCHAR2(10);
|
||||||
|
vRestoreGrantsStr VARCHAR2(10);
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Convert BOOLEAN to VARCHAR2 for logging
|
-- Convert BOOLEAN to VARCHAR2 for logging
|
||||||
vRecreateStr := CASE WHEN pRecreate THEN 'TRUE' ELSE 'FALSE' END;
|
vRecreateStr := CASE WHEN pRecreate THEN 'TRUE' ELSE 'FALSE' END;
|
||||||
|
vRestoreGrantsStr := CASE WHEN pRestoreGrants THEN 'TRUE' ELSE 'FALSE' END;
|
||||||
|
|
||||||
-- Log the start of the procedure
|
-- Log the start of the procedure
|
||||||
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(
|
vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(
|
||||||
@@ -126,7 +138,9 @@ AS
|
|||||||
'pSourceKey => ''' || NVL(pSourceKey, 'NULL') || '''',
|
'pSourceKey => ''' || NVL(pSourceKey, 'NULL') || '''',
|
||||||
'pSourceFileId => ''' || NVL(pSourceFileId, 'NULL') || '''',
|
'pSourceFileId => ''' || NVL(pSourceFileId, 'NULL') || '''',
|
||||||
'pTableId => ''' || NVL(pTableId, 'NULL') || '''',
|
'pTableId => ''' || NVL(pTableId, 'NULL') || '''',
|
||||||
'pRecreate => ' || vRecreateStr
|
'pRecreate => ' || vRecreateStr,
|
||||||
|
'pRestoreGrants => ' || vRestoreGrantsStr,
|
||||||
|
'pArea => ''' || pArea || ''''
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -139,7 +153,9 @@ AS
|
|||||||
pSourceKey => pSourceKey,
|
pSourceKey => pSourceKey,
|
||||||
pSourceFileId => pSourceFileId,
|
pSourceFileId => pSourceFileId,
|
||||||
pTableId => pTableId,
|
pTableId => pTableId,
|
||||||
pRecreate => pRecreate
|
pRecreate => pRecreate,
|
||||||
|
pRestoreGrants => pRestoreGrants,
|
||||||
|
pArea => pArea
|
||||||
);
|
);
|
||||||
|
|
||||||
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_BATCH', 'INFO', vParameters);
|
CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_BATCH', 'INFO', vParameters);
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ AS
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
||||||
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '2.2.0';
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '2.4.0';
|
||||||
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-11-27 15:00:00';
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-18 16: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) :=
|
||||||
|
'2.4.0 (2026-02-18): MARS-1057 - Added pArea parameter for selective table creation (INBOX/ODS/ARCHIVE/ALL)' || CHR(13)||CHR(10) ||
|
||||||
|
'2.3.0 (2026-02-18): MARS-1057 - Added pRestoreGrants parameter support for grant preservation during table recreate' || CHR(13)||CHR(10) ||
|
||||||
'2.2.0 (2025-11-27): MARS-1057 - Added CREATE_EXTERNAL_TABLES_SET and CREATE_EXTERNAL_TABLES_BATCH wrappers for batch external table creation' || CHR(13)||CHR(10) ||
|
'2.2.0 (2025-11-27): MARS-1057 - Added CREATE_EXTERNAL_TABLES_SET and CREATE_EXTERNAL_TABLES_BATCH wrappers for batch external table creation' || CHR(13)||CHR(10) ||
|
||||||
'2.1.0 (2025-11-24): MARS-1049 - Added pEncoding parameter support for CSV character set specification' || CHR(13)||CHR(10) ||
|
'2.1.0 (2025-11-24): MARS-1049 - Added pEncoding parameter support for CSV character set specification' || 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) ||
|
||||||
@@ -63,45 +65,62 @@ AS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @name CREATE_EXTERNAL_TABLES_SET
|
* @name CREATE_EXTERNAL_TABLES_SET
|
||||||
* @desc Creates a complete set of 3 external tables (INBOX, ODS, ARCHIVE) for a single configuration
|
* @desc Creates a complete set of external tables for a single configuration from A_SOURCE_FILE_CONFIG table.
|
||||||
* from A_SOURCE_FILE_CONFIG table. Automatically generates table names and paths following
|
* Automatically generates table names and paths following official path patterns.
|
||||||
* official path patterns. Wrapper for CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET
|
* Wrapper for CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLES_SET with DEFINER rights.
|
||||||
* with DEFINER rights to ensure objects are created in ODS schema.
|
* If pRestoreGrants is TRUE, saves and restores table grants during recreate operation.
|
||||||
|
* The pArea parameter allows selective table creation.
|
||||||
* @param pSourceFileConfigKey - Primary key from A_SOURCE_FILE_CONFIG table
|
* @param pSourceFileConfigKey - Primary key from A_SOURCE_FILE_CONFIG table
|
||||||
* @param pRecreate - If TRUE, drops existing tables before creating new ones; if FALSE, fails if tables exist
|
* @param pRecreate - If TRUE, drops existing tables before creating new ones; if FALSE, fails if tables exist
|
||||||
* @example EXEC ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_SET(
|
* @param pRestoreGrants - If TRUE, saves grants before DROP and restores after CREATE (only when pRecreate=TRUE)
|
||||||
|
* Uses DBA_TAB_PRIVS - requires SELECT ANY DICTIONARY or SELECT ON DBA_TAB_PRIVS privilege
|
||||||
|
* @param pArea - Specifies which tables to create: 'INBOX', 'ODS', 'ARCHIVE', or 'ALL' (default)
|
||||||
|
* @example -- Create only INBOX table
|
||||||
|
* EXEC ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_SET(
|
||||||
* pSourceFileConfigKey => 123,
|
* pSourceFileConfigKey => 123,
|
||||||
* pRecreate => FALSE
|
* pArea => 'INBOX'
|
||||||
* );
|
* );
|
||||||
* @ex_rslt Creates three external tables in ODS schema:
|
*
|
||||||
* - C2D_A_UC_DISSEM_METADATA_LOADS_INBOX
|
* -- Create all tables with grant preservation
|
||||||
* - C2D_A_UC_DISSEM_METADATA_LOADS_ODS
|
* EXEC ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_SET(
|
||||||
* - C2D_A_UC_DISSEM_METADATA_LOADS_ARCHIVE
|
* pSourceFileConfigKey => 123,
|
||||||
|
* pRecreate => TRUE,
|
||||||
|
* pRestoreGrants => TRUE,
|
||||||
|
* pArea => 'ALL'
|
||||||
|
* );
|
||||||
|
* @ex_rslt Creates external table(s) in ODS schema based on pArea parameter
|
||||||
*/
|
*/
|
||||||
PROCEDURE CREATE_EXTERNAL_TABLES_SET (
|
PROCEDURE CREATE_EXTERNAL_TABLES_SET (
|
||||||
pSourceFileConfigKey IN NUMBER,
|
pSourceFileConfigKey IN NUMBER,
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
pRecreate IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pRestoreGrants IN BOOLEAN DEFAULT TRUE,
|
||||||
|
pArea IN VARCHAR2 DEFAULT 'ALL'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name CREATE_EXTERNAL_TABLES_BATCH
|
* @name CREATE_EXTERNAL_TABLES_BATCH
|
||||||
* @desc Creates external table sets for multiple configurations based on filter criteria.
|
* @desc Creates external table sets for multiple configurations based on filter criteria.
|
||||||
* Processes only INPUT type files from A_SOURCE_FILE_CONFIG. Creates 3 tables per configuration
|
* Processes only INPUT type files from A_SOURCE_FILE_CONFIG. Creates tables based on pArea parameter.
|
||||||
* (INBOX, ODS, ARCHIVE). Wrapper for CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH
|
* Wrapper for CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH with DEFINER rights.
|
||||||
* with DEFINER rights to ensure objects are created in ODS schema.
|
* If pRestoreGrants is TRUE, saves and restores table grants during recreate operations.
|
||||||
* @param pSourceKey - Filter by A_SOURCE_KEY (NULL = all sources)
|
* @param pSourceKey - Filter by A_SOURCE_KEY (NULL = all sources)
|
||||||
* @param pSourceFileId - Filter by SOURCE_FILE_ID (NULL = all file types)
|
* @param pSourceFileId - Filter by SOURCE_FILE_ID (NULL = all file types)
|
||||||
* @param pTableId - Filter by TABLE_ID (NULL = all tables)
|
* @param pTableId - Filter by TABLE_ID (NULL = all tables)
|
||||||
* @param pRecreate - If TRUE, drops and recreates existing tables; if FALSE, skips if tables exist
|
* @param pRecreate - If TRUE, drops and recreates existing tables; if FALSE, skips if tables exist
|
||||||
* @example -- Create all external tables for C2D source
|
* @param pRestoreGrants - If TRUE, saves grants before DROP and restores after CREATE (only when pRecreate=TRUE)
|
||||||
|
* Uses DBA_TAB_PRIVS - requires SELECT ANY DICTIONARY or SELECT ON DBA_TAB_PRIVS privilege
|
||||||
|
* @param pArea - Specifies which tables to create: 'INBOX', 'ODS', 'ARCHIVE', or 'ALL' (default)
|
||||||
|
* @example -- Create only INBOX tables for C2D source
|
||||||
* EXEC ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_BATCH(
|
* EXEC ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_BATCH(
|
||||||
* pSourceKey => 'C2D',
|
* pSourceKey => 'C2D',
|
||||||
* pRecreate => FALSE
|
* pArea => 'INBOX'
|
||||||
* );
|
* );
|
||||||
*
|
*
|
||||||
* -- Recreate all external tables for all sources
|
* -- Create all tables with grant preservation
|
||||||
* EXEC ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_BATCH(
|
* EXEC ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLES_BATCH(
|
||||||
* pRecreate => TRUE
|
* pRecreate => TRUE,
|
||||||
|
* pRestoreGrants => TRUE,
|
||||||
|
* pArea => 'ALL'
|
||||||
* );
|
* );
|
||||||
* @ex_rslt Returns summary: Total: 10, Processed: 9, Failed: 1
|
* @ex_rslt Returns summary: Total: 10, Processed: 9, Failed: 1
|
||||||
*/
|
*/
|
||||||
@@ -109,7 +128,9 @@ AS
|
|||||||
pSourceKey IN VARCHAR2 DEFAULT NULL,
|
pSourceKey IN VARCHAR2 DEFAULT NULL,
|
||||||
pSourceFileId IN VARCHAR2 DEFAULT NULL,
|
pSourceFileId IN VARCHAR2 DEFAULT NULL,
|
||||||
pTableId IN VARCHAR2 DEFAULT NULL,
|
pTableId IN VARCHAR2 DEFAULT NULL,
|
||||||
pRecreate IN BOOLEAN DEFAULT FALSE
|
pRecreate IN BOOLEAN DEFAULT FALSE,
|
||||||
|
pRestoreGrants IN BOOLEAN DEFAULT TRUE,
|
||||||
|
pArea IN VARCHAR2 DEFAULT 'ALL'
|
||||||
);
|
);
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- MARS-1057 ROLLBACK SCRIPT: Batch External Table Creation
|
-- MARS-1057 ROLLBACK SCRIPT: Batch External Table Creation
|
||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
-- Purpose: Rollback FILE_MANAGER package to v3.3.0 (remove batch external table procedures)
|
-- Purpose: Rollback FILE_MANAGER package to v3.3.0 (remove batch external table procedures and area filter)
|
||||||
-- Author: Grzegorz Michalski
|
-- Author: Grzegorz Michalski
|
||||||
-- Date: 2025-11-27
|
-- Date: 2026-02-18
|
||||||
|
|
||||||
-- Dynamic spool file generation (using SYS_CONTEXT - no DBA privileges required)
|
-- Dynamic spool file generation (using SYS_CONTEXT - no DBA privileges required)
|
||||||
-- Log files are automatically created in log/ subdirectory
|
-- Log files are automatically created in log/ subdirectory
|
||||||
@@ -25,17 +25,19 @@ SET SERVEROUTPUT ON SIZE UNLIMITED
|
|||||||
SET PAUSE OFF
|
SET PAUSE OFF
|
||||||
|
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT MARS-1057: Rollback Batch External Table Creation
|
PROMPT MARS-1057: Rollback Batch External Table Creation + Area Filter
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT WARNING: This will reverse all changes from MARS-1057 installation!
|
PROMPT WARNING: This will reverse all changes from MARS-1057 installation!
|
||||||
PROMPT
|
PROMPT
|
||||||
PROMPT Changes to be rolled back:
|
PROMPT Changes to be rolled back:
|
||||||
PROMPT - FILE_MANAGER package specification (3.4.0 -> 3.3.0)
|
PROMPT - FILE_MANAGER package specification (3.5.0 -> 3.3.0)
|
||||||
PROMPT - FILE_MANAGER package body (3.4.0 -> 3.3.0)
|
PROMPT - FILE_MANAGER package body (3.5.0 -> 3.3.0)
|
||||||
PROMPT - FILE_MANAGER_ODS package specification (2.2.0 -> 2.1.0)
|
PROMPT - FILE_MANAGER_ODS package specification (2.4.0 -> 2.1.0)
|
||||||
PROMPT - FILE_MANAGER_ODS package body (2.2.0 -> 2.1.0)
|
PROMPT - FILE_MANAGER_ODS package body (2.4.0 -> 2.1.0)
|
||||||
PROMPT - Remove CREATE_EXTERNAL_TABLES_SET procedures
|
PROMPT - Remove CREATE_EXTERNAL_TABLES_SET procedures
|
||||||
PROMPT - Remove CREATE_EXTERNAL_TABLES_BATCH procedures
|
PROMPT - Remove CREATE_EXTERNAL_TABLES_BATCH procedures
|
||||||
|
PROMPT - Remove pArea parameter (selective table creation)
|
||||||
|
PROMPT - Remove pRestoreGrants parameter (grant preservation)
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
|
|
||||||
-- Confirm rollback with user
|
-- Confirm rollback with user
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,22 +9,65 @@ AS
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
-- Package Version Information
|
-- Package Version Information
|
||||||
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '2.1.1';
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '2.6.3';
|
||||||
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(19) := '2025-12-04 13:10:00';
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(19) := '2026-01-28 19:30:00';
|
||||||
PACKAGE_AUTHOR CONSTANT VARCHAR2(50) := 'MRDS Development Team';
|
PACKAGE_AUTHOR CONSTANT VARCHAR2(50) := 'MRDS Development Team';
|
||||||
|
|
||||||
-- Version History (last 3-5 changes)
|
-- Version History (last 3-5 changes)
|
||||||
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
|
||||||
|
'v2.6.3 (2026-01-28): COMPILATION FIX - Resolved ORA-00904 error in EXPORT_PARTITION_PARALLEL. SQLERRM and DBMS_UTILITY.FORMAT_ERROR_BACKTRACE cannot be used directly in SQL UPDATE statements. Now properly assigned to vgMsgTmp variable before UPDATE.' || CHR(10) ||
|
||||||
|
'v2.6.2 (2026-01-28): CRITICAL FIX - Race condition when multiple exports run simultaneously. Changed DELETE to filter by age (>24h) instead of deleting all COMPLETED chunks. Prevents concurrent sessions from deleting each other chunks. Session-safe cleanup with TASK_NAME filtering. Enables true parallel execution of multiple export jobs.' || CHR(10) ||
|
||||||
|
'v2.6.1 (2026-01-28): Added DELETE_FAILED_EXPORT_FILE procedure to clean up partial/corrupted files before retry. When partition fails mid-export, partial file is deleted before retry to prevent Oracle from creating _1 suffixed duplicates. Ensures clean retry without orphaned files in OCI bucket.' || CHR(10) ||
|
||||||
|
'v2.6.0 (2026-01-28): CRITICAL FIX - Added STATUS tracking to A_PARALLEL_EXPORT_CHUNKS table to prevent data duplication on retry. System now restarts ONLY failed partitions instead of re-exporting all data. Added ERROR_MESSAGE and EXPORT_TIMESTAMP columns for better error handling and monitoring. Prevents duplicate file creation when parallel tasks fail (e.g., 22 partitions with 16 threads, 3 failures no longer duplicates 19 successful exports).' || CHR(10) ||
|
||||||
|
'v2.5.0 (2026-01-26): Added recorddelimiter parameter with CRLF (CHR(13)||CHR(10)) for CSV exports to ensure Windows-compatible line endings. Improves cross-platform compatibility when CSV files are opened in Windows applications (Notepad, Excel).' || CHR(10) ||
|
||||||
|
'v2.4.0 (2026-01-11): Added pTemplateTableName parameter for per-column date format configuration. Implements dynamic query building with TO_CHAR for each date/timestamp column using FILE_MANAGER.GET_DATE_FORMAT. Supports 3-tier hierarchy: column-specific, template DEFAULT, global fallback. Eliminates single dateformat limitation of DBMS_CLOUD.EXPORT_DATA.' || CHR(10) ||
|
||||||
|
'v2.3.0 (2025-12-20): Added parallel partition processing using DBMS_PARALLEL_EXECUTE. New pParallelDegree parameter (1-16, default 1) for EXPORT_TABLE_DATA_BY_DATE and EXPORT_TABLE_DATA_TO_CSV_BY_DATE procedures. Each year/month partition processed in separate thread for improved performance.' || CHR(10) ||
|
||||||
|
'v2.2.0 (2025-12-19): DRY refactoring - extracted shared helper functions (sanitizeFilename, VALIDATE_TABLE_AND_COLUMNS, GET_PARTITIONS, EXPORT_SINGLE_PARTITION worker procedure). Reduced code duplication by ~400 lines. Prepared architecture for v2.3.0 parallel processing.' || CHR(10) ||
|
||||||
'v2.1.1 (2025-12-04): Fixed JOIN column reference A_WORKFLOW_HISTORY_KEY -> A_ETL_LOAD_SET_KEY, added consistent column mapping and dynamic column list to EXPORT_TABLE_DATA procedure, enhanced DEBUG logging for all export operations' || CHR(10) ||
|
'v2.1.1 (2025-12-04): Fixed JOIN column reference A_WORKFLOW_HISTORY_KEY -> A_ETL_LOAD_SET_KEY, added consistent column mapping and dynamic column list to EXPORT_TABLE_DATA procedure, enhanced DEBUG logging for all export operations' || CHR(10) ||
|
||||||
'v2.1.1 (2025-12-04): Fixed JOIN column reference A_WORKFLOW_HISTORY_KEY -> A_ETL_LOAD_SET_KEY' || CHR(10) ||
|
|
||||||
'v2.1.0 (2025-10-22): Added version tracking and PARTITION_YEAR/PARTITION_MONTH support' || CHR(10) ||
|
'v2.1.0 (2025-10-22): Added version tracking and PARTITION_YEAR/PARTITION_MONTH support' || CHR(10) ||
|
||||||
'v2.0.0 (2025-10-01): Separated export functionality from FILE_MANAGER package' || CHR(10) ||
|
'v2.0.0 (2025-10-01): Separated export functionality from FILE_MANAGER package' || CHR(10);
|
||||||
'v1.0.0 (2025-09-15): Initial implementation within FILE_MANAGER package' || CHR(10);
|
|
||||||
|
|
||||||
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10);
|
||||||
vgMsgTmp VARCHAR2(32000);
|
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
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,6 +105,7 @@ AS
|
|||||||
* Allows specifying custom column list or uses T.* if pColumnList is NULL.
|
* Allows specifying custom column list or uses T.* if pColumnList is NULL.
|
||||||
* Validates that all columns in pColumnList exist in the target table.
|
* Validates that all columns in pColumnList exist in the target table.
|
||||||
* Automatically adds 'T.' prefix to column names in pColumnList.
|
* 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'
|
* pBucketArea parameter accepts: 'INBOX', 'ODS', 'DATA', 'ARCHIVE'
|
||||||
* @example
|
* @example
|
||||||
* begin
|
* begin
|
||||||
@@ -73,7 +117,8 @@ AS
|
|||||||
* pFolderName => 'parquet_exports',
|
* pFolderName => 'parquet_exports',
|
||||||
* pColumnList => 'COLUMN1, COLUMN2, COLUMN3', -- Optional
|
* pColumnList => 'COLUMN1, COLUMN2, COLUMN3', -- Optional
|
||||||
* pMinDate => DATE '2024-01-01',
|
* pMinDate => DATE '2024-01-01',
|
||||||
* pMaxDate => SYSDATE
|
* pMaxDate => SYSDATE,
|
||||||
|
* pParallelDegree => 8 -- Optional, default 1, range 1-16
|
||||||
* );
|
* );
|
||||||
* end;
|
* end;
|
||||||
**/
|
**/
|
||||||
@@ -86,6 +131,8 @@ AS
|
|||||||
pColumnList IN VARCHAR2 default NULL,
|
pColumnList IN VARCHAR2 default NULL,
|
||||||
pMinDate IN DATE default DATE '1900-01-01',
|
pMinDate IN DATE default DATE '1900-01-01',
|
||||||
pMaxDate IN DATE default SYSDATE,
|
pMaxDate IN DATE default SYSDATE,
|
||||||
|
pParallelDegree IN NUMBER default 1,
|
||||||
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -97,6 +144,7 @@ AS
|
|||||||
* Creates one CSV file for each year/month combination found in the data.
|
* 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,
|
* 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.
|
* 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)
|
* File naming pattern: {pFileName}_YYYYMM.csv or {TABLENAME}_YYYYMM.csv (if pFileName is NULL)
|
||||||
* @example
|
* @example
|
||||||
* begin
|
* begin
|
||||||
@@ -109,7 +157,8 @@ AS
|
|||||||
* pFolderName => 'exports',
|
* pFolderName => 'exports',
|
||||||
* pFileName => 'my_export.csv',
|
* pFileName => 'my_export.csv',
|
||||||
* pMinDate => DATE '2024-01-01',
|
* pMinDate => DATE '2024-01-01',
|
||||||
* pMaxDate => SYSDATE
|
* pMaxDate => SYSDATE,
|
||||||
|
* pParallelDegree => 8 -- Optional, default 1, range 1-16
|
||||||
* );
|
* );
|
||||||
*
|
*
|
||||||
* -- With auto-generated filename (based on table name only)
|
* -- With auto-generated filename (based on table name only)
|
||||||
@@ -136,6 +185,9 @@ AS
|
|||||||
pColumnList IN VARCHAR2 default NULL,
|
pColumnList IN VARCHAR2 default NULL,
|
||||||
pMinDate IN DATE default DATE '1900-01-01',
|
pMinDate IN DATE default DATE '1900-01-01',
|
||||||
pMaxDate IN DATE default SYSDATE,
|
pMaxDate IN DATE default SYSDATE,
|
||||||
|
pParallelDegree IN NUMBER default 1,
|
||||||
|
pTemplateTableName IN VARCHAR2 default NULL,
|
||||||
|
pMaxFileSize IN NUMBER default 104857600,
|
||||||
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ AS
|
|||||||
Errors(CODE_MOVE_FILE_TO_TRASH_FAILED) := Error_Record(CODE_MOVE_FILE_TO_TRASH_FAILED, MSG_MOVE_FILE_TO_TRASH_FAILED); -- -20032
|
Errors(CODE_MOVE_FILE_TO_TRASH_FAILED) := Error_Record(CODE_MOVE_FILE_TO_TRASH_FAILED, MSG_MOVE_FILE_TO_TRASH_FAILED); -- -20032
|
||||||
Errors(CODE_DROP_EXPORTED_FILES_FAILED) := Error_Record(CODE_DROP_EXPORTED_FILES_FAILED, MSG_DROP_EXPORTED_FILES_FAILED); -- -20033
|
Errors(CODE_DROP_EXPORTED_FILES_FAILED) := Error_Record(CODE_DROP_EXPORTED_FILES_FAILED, MSG_DROP_EXPORTED_FILES_FAILED); -- -20033
|
||||||
Errors(CODE_INVALID_BUCKET_AREA) := Error_Record(CODE_INVALID_BUCKET_AREA, MSG_INVALID_BUCKET_AREA); -- -20034
|
Errors(CODE_INVALID_BUCKET_AREA) := Error_Record(CODE_INVALID_BUCKET_AREA, MSG_INVALID_BUCKET_AREA); -- -20034
|
||||||
|
Errors(CODE_INVALID_PARALLEL_DEGREE) := Error_Record(CODE_INVALID_PARALLEL_DEGREE, MSG_INVALID_PARALLEL_DEGREE); -- -20110
|
||||||
|
Errors(CODE_PARALLEL_EXECUTION_FAILED) := Error_Record(CODE_PARALLEL_EXECUTION_FAILED, MSG_PARALLEL_EXECUTION_FAILED); -- -20111
|
||||||
|
|
||||||
Errors(CODE_UNKNOWN) := Error_Record(CODE_UNKNOWN, MSG_UNKNOWN); -- -20999
|
Errors(CODE_UNKNOWN) := Error_Record(CODE_UNKNOWN, MSG_UNKNOWN); -- -20999
|
||||||
|
|
||||||
@@ -1163,3 +1165,7 @@ BEGIN
|
|||||||
|
|
||||||
INIT_VARIABLES(pEnv => gvEnv);
|
INIT_VARIABLES(pEnv => gvEnv);
|
||||||
END ENV_MANAGER;
|
END ENV_MANAGER;
|
||||||
|
|
||||||
|
/
|
||||||
|
|
||||||
|
/
|
||||||
|
|||||||
@@ -17,12 +17,13 @@ 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.2.0';
|
||||||
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-10-22 20:57:00';
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-12-20 10: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.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.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) ||
|
'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.1.0 (2025-10-15): Added ANALYZE_VALIDATION_ERRORS function for comprehensive CSV validation analysis' || CHR(13)||CHR(10) ||
|
||||||
@@ -296,6 +297,18 @@ AS
|
|||||||
PRAGMA EXCEPTION_INIT( ERR_INVALID_BUCKET_AREA
|
PRAGMA EXCEPTION_INIT( ERR_INVALID_BUCKET_AREA
|
||||||
,CODE_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;
|
ERR_UNKNOWN EXCEPTION;
|
||||||
CODE_UNKNOWN CONSTANT PLS_INTEGER := -20999;
|
CODE_UNKNOWN CONSTANT PLS_INTEGER := -20999;
|
||||||
MSG_UNKNOWN VARCHAR2(4000) := 'Unknown Error Occured';
|
MSG_UNKNOWN VARCHAR2(4000) := 'Unknown Error Occured';
|
||||||
@@ -609,3 +622,4 @@ AS
|
|||||||
) RETURN VARCHAR2;
|
) RETURN VARCHAR2;
|
||||||
|
|
||||||
END ENV_MANAGER;
|
END ENV_MANAGER;
|
||||||
|
/
|
||||||
|
|||||||
@@ -1,6 +1,54 @@
|
|||||||
create or replace PACKAGE BODY CT_MRDS.FILE_ARCHIVER
|
create or replace PACKAGE BODY CT_MRDS.FILE_ARCHIVER
|
||||||
AS
|
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 four strategies: THRESHOLD_BASED, CURRENT_MONTH_ONLY, 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 all data except current month
|
||||||
|
WHEN 'CURRENT_MONTH_ONLY' THEN
|
||||||
|
vWhereClause := 'TRUNC(workflow_start, ''MM'') < TRUNC(SYSDATE, ''MM'')';
|
||||||
|
|
||||||
|
-- Archive only data older than X months
|
||||||
|
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)
|
FUNCTION GET_TABLE_STAT(pSourceFileConfigKey IN NUMBER)
|
||||||
@@ -85,6 +133,8 @@ AS
|
|||||||
if LENGTH(vArchivalTriggeredBy)>0 THEN
|
if LENGTH(vArchivalTriggeredBy)>0 THEN
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Archival Triggered By: '||vArchivalTriggeredBy,'INFO');
|
ENV_MANAGER.LOG_PROCESS_EVENT('Archival Triggered By: '||vArchivalTriggeredBy,'INFO');
|
||||||
vTableName := DBMS_ASSERT.SCHEMA_NAME(vSourceFileConfig.ODS_SCHEMA_NAME) || '.'||vSourceFileConfig.A_SOURCE_KEY||'_'||DBMS_ASSERT.simple_sql_name(vSourceFileConfig.TABLE_ID)||'_ODS';
|
vTableName := DBMS_ASSERT.SCHEMA_NAME(vSourceFileConfig.ODS_SCHEMA_NAME) || '.'||vSourceFileConfig.A_SOURCE_KEY||'_'||DBMS_ASSERT.simple_sql_name(vSourceFileConfig.TABLE_ID)||'_ODS';
|
||||||
|
|
||||||
|
-- Use strategy-based WHERE clause (MARS-828)
|
||||||
vQuery := '
|
vQuery := '
|
||||||
select t_filename(
|
select t_filename(
|
||||||
file$name
|
file$name
|
||||||
@@ -96,7 +146,7 @@ AS
|
|||||||
from '||vTableName||' s
|
from '||vTableName||' s
|
||||||
join CT_MRDS.a_workflow_history h
|
join CT_MRDS.a_workflow_history h
|
||||||
on s.a_workflow_history_key = h.a_workflow_history_key
|
on s.a_workflow_history_key = h.a_workflow_history_key
|
||||||
where extract(day from (systimestamp - workflow_start)) > '||vSourceFileConfig.DAYS_FOR_ARCHIVE_THRESHOLD
|
where ' || GET_ARCHIVAL_WHERE_CLAUSE(vSourceFileConfig)
|
||||||
;
|
;
|
||||||
|
|
||||||
-- Get all files that will be archived into "vfiles" collection ("regular data files")
|
-- Get all files that will be archived into "vfiles" collection ("regular data files")
|
||||||
@@ -337,6 +387,7 @@ AS
|
|||||||
vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE;
|
vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE;
|
||||||
vTableName VARCHAR2(200);
|
vTableName VARCHAR2(200);
|
||||||
vQuery VARCHAR2(32000);
|
vQuery VARCHAR2(32000);
|
||||||
|
vWhereClause VARCHAR2(4000);
|
||||||
BEGIN
|
BEGIN
|
||||||
vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL')));
|
vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL')));
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
@@ -344,6 +395,12 @@ AS
|
|||||||
|
|
||||||
vTableName := DBMS_ASSERT.SCHEMA_NAME(vSourceFileConfig.ODS_SCHEMA_NAME) || '.'||vSourceFileConfig.A_SOURCE_KEY||'_'||DBMS_ASSERT.simple_sql_name(vSourceFileConfig.TABLE_ID)||'_ODS';
|
vTableName := DBMS_ASSERT.SCHEMA_NAME(vSourceFileConfig.ODS_SCHEMA_NAME) || '.'||vSourceFileConfig.A_SOURCE_KEY||'_'||DBMS_ASSERT.simple_sql_name(vSourceFileConfig.TABLE_ID)||'_ODS';
|
||||||
ENV_MANAGER.LOG_PROCESS_EVENT('vTableName','DEBUG',vTableName);
|
ENV_MANAGER.LOG_PROCESS_EVENT('vTableName','DEBUG',vTableName);
|
||||||
|
|
||||||
|
-- Get WHERE clause based on archival strategy (MARS-828)
|
||||||
|
vWhereClause := GET_ARCHIVAL_WHERE_CLAUSE(vSourceFileConfig);
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('vWhereClause','DEBUG',vWhereClause);
|
||||||
|
|
||||||
|
-- Use strategy-based WHERE clause for statistics (MARS-828)
|
||||||
vQuery :=
|
vQuery :=
|
||||||
'with tmp as (
|
'with tmp as (
|
||||||
select
|
select
|
||||||
@@ -367,11 +424,11 @@ AS
|
|||||||
,'||pSourceFileConfigKey||' as A_SOURCE_FILE_CONFIG_KEY
|
,'||pSourceFileConfigKey||' as A_SOURCE_FILE_CONFIG_KEY
|
||||||
,'''||vTableName||''' as TABLE_NAME
|
,'''||vTableName||''' as TABLE_NAME
|
||||||
,count(*) as FILE_COUNT
|
,count(*) as FILE_COUNT
|
||||||
,sum(case when extract(day from (systimestamp - workflow_start)) > '||vSourceFileConfig.DAYS_FOR_ARCHIVE_THRESHOLD||' then 1 else 0 end) as OLD_FILE_COUNT
|
,sum(case when ' || vWhereClause || ' then 1 else 0 end) as OLD_FILE_COUNT
|
||||||
,sum (row_count_per_file) as ROW_COUNT
|
,sum (row_count_per_file) as ROW_COUNT
|
||||||
,sum(case when extract(day from (systimestamp - workflow_start)) > '||vSourceFileConfig.DAYS_FOR_ARCHIVE_THRESHOLD||' then row_count_per_file else 0 end) as OLD_ROW_COUNT
|
,sum(case when ' || vWhereClause || ' then row_count_per_file else 0 end) as OLD_ROW_COUNT
|
||||||
,sum(r.bytes) as BYTES
|
,sum(r.bytes) as BYTES
|
||||||
,sum(case when extract(day from (systimestamp - workflow_start)) > '||vSourceFileConfig.DAYS_FOR_ARCHIVE_THRESHOLD||' then r.bytes else 0 end) as OLD_BYTES
|
,sum(case when ' || vWhereClause || ' then r.bytes else 0 end) as OLD_BYTES
|
||||||
,'||vSourceFileConfig.DAYS_FOR_ARCHIVE_THRESHOLD||' as DAYS_FOR_ARCHIVE_THRESHOLD
|
,'||vSourceFileConfig.DAYS_FOR_ARCHIVE_THRESHOLD||' as DAYS_FOR_ARCHIVE_THRESHOLD
|
||||||
,systimestamp as CREATED
|
,systimestamp as CREATED
|
||||||
from tmp_gr t
|
from tmp_gr t
|
||||||
@@ -438,6 +495,48 @@ AS
|
|||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FUNCTION ARCHIVE_TABLE_DATA (
|
||||||
|
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 := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL')));
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
----
|
||||||
|
ARCHIVE_TABLE_DATA(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
----
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT(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 := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL')));
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters);
|
||||||
|
----
|
||||||
|
GATHER_TABLE_STAT(pSourceFileConfigKey => pSourceFileConfigKey);
|
||||||
|
----
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters);
|
||||||
|
RETURN SQLCODE;
|
||||||
|
END GATHER_TABLE_STAT;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
END;
|
END;
|
||||||
|
|
||||||
/
|
/
|
||||||
|
|||||||
@@ -17,12 +17,14 @@ AS
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
|
||||||
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '2.0.0';
|
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.1.0';
|
||||||
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-10-22 16:45:00';
|
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-01-29 21: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.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) ||
|
||||||
'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';
|
||||||
@@ -39,6 +41,18 @@ AS
|
|||||||
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
|
||||||
|
* @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.
|
||||||
|
* @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
|
||||||
|
) RETURN PLS_INTEGER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,6 +64,18 @@ AS
|
|||||||
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 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;
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
-- PACKAGE VERSION MANAGEMENT FUNCTIONS
|
-- PACKAGE VERSION MANAGEMENT FUNCTIONS
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
-- ====================================================================
|
-- ====================================================================
|
||||||
-- Purpose: Store source file configuration and processing rules
|
-- Purpose: Store source file configuration and processing rules
|
||||||
-- MARS-1049: Added ENCODING column for CSV character set support
|
-- 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 (
|
CREATE TABLE CT_MRDS.A_SOURCE_FILE_CONFIG (
|
||||||
@@ -21,8 +22,14 @@ CREATE TABLE CT_MRDS.A_SOURCE_FILE_CONFIG (
|
|||||||
ODS_SCHEMA_NAME VARCHAR2(100),
|
ODS_SCHEMA_NAME VARCHAR2(100),
|
||||||
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD NUMBER(38,0),
|
ROWS_COUNT_OVER_ARCHIVE_THRESHOLD NUMBER(38,0),
|
||||||
HOURS_TO_EXPIRE_STATISTICS NUMBER(38,3),
|
HOURS_TO_EXPIRE_STATISTICS NUMBER(38,3),
|
||||||
|
ARCHIVAL_STRATEGY VARCHAR2(50),
|
||||||
|
MINIMUM_AGE_MONTHS NUMBER(3,0),
|
||||||
ENCODING VARCHAR2(50) DEFAULT 'UTF8',
|
ENCODING VARCHAR2(50) DEFAULT 'UTF8',
|
||||||
|
ARCHIVE_ENABLED CHAR(1) DEFAULT 'Y' NOT NULL,
|
||||||
|
KEEP_IN_TRASH CHAR(1) DEFAULT 'N' NOT NULL,
|
||||||
CONSTRAINT A_SOURCE_FILE_CONFIG_PK PRIMARY KEY (A_SOURCE_FILE_CONFIG_KEY),
|
CONSTRAINT A_SOURCE_FILE_CONFIG_PK PRIMARY KEY (A_SOURCE_FILE_CONFIG_KEY),
|
||||||
|
CONSTRAINT CHK_ARCHIVE_ENABLED CHECK (ARCHIVE_ENABLED IN ('Y', 'N')),
|
||||||
|
CONSTRAINT CHK_KEEP_IN_TRASH CHECK (KEEP_IN_TRASH IN ('Y', 'N')),
|
||||||
CONSTRAINT SOURCE_FILE_TYPE_CHK CHECK (SOURCE_FILE_TYPE IN ('INPUT', 'CONTAINER', 'LOAD_CONFIG')),
|
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_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 ASFC_CONTAINER_FILE_KEY_FK FOREIGN KEY(CONTAINER_FILE_KEY) REFERENCES CT_MRDS.A_SOURCE_FILE_CONFIG(A_SOURCE_FILE_CONFIG_KEY),
|
||||||
@@ -40,6 +47,10 @@ ON "CT_MRDS"."A_SOURCE_FILE_CONFIG" ("SOURCE_FILE_TYPE", "SOURCE_FILE_ID", "TABL
|
|||||||
TABLESPACE "DATA";
|
TABLESPACE "DATA";
|
||||||
|
|
||||||
-- Column comments
|
-- Column comments
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ARCHIVAL_STRATEGY IS 'Archival strategy: THRESHOLD_BASED, CURRENT_MONTH_ONLY, MINIMUM_AGE_MONTHS, HYBRID. Added in MARS-828';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.MINIMUM_AGE_MONTHS IS 'Minimum age in months before archival (required for MINIMUM_AGE_MONTHS strategy). Added in MARS-828';
|
||||||
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING IS 'Oracle character set name for CSV files (e.g., UTF8, WE8MSWIN1252, EE8ISO8859P2). Added in MARS-1049';
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING IS 'Oracle character set name for CSV files (e.g., UTF8, WE8MSWIN1252, EE8ISO8859P2). Added in MARS-1049';
|
||||||
|
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.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.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';
|
||||||
|
|
||||||
GRANT SELECT, INSERT, UPDATE, DELETE ON CT_MRDS.A_SOURCE_FILE_CONFIG TO MRDS_LOADER_ROLE;
|
GRANT SELECT, INSERT, UPDATE, DELETE ON CT_MRDS.A_SOURCE_FILE_CONFIG TO MRDS_LOADER_ROLE;
|
||||||
@@ -19,7 +19,7 @@ CREATE TABLE CT_MRDS.A_SOURCE_FILE_RECEIVED (
|
|||||||
ARCH_FILE_NAME VARCHAR2(1000),
|
ARCH_FILE_NAME VARCHAR2(1000),
|
||||||
CONSTRAINT A_SOURCE_FILE_RECEIVED_PK PRIMARY KEY (A_SOURCE_FILE_RECEIVED_KEY),
|
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 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'))
|
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";
|
) TABLESPACE "DATA";
|
||||||
|
|
||||||
-- Unique index for file identification (workaround for TIMESTAMP WITH TIMEZONE constraint limitation)
|
-- Unique index for file identification (workaround for TIMESTAMP WITH TIMEZONE constraint limitation)
|
||||||
|
|||||||
@@ -73,6 +73,12 @@ echo 'yes' | sql "ADMIN/Cloudpass#34@ggmichalski_high" "@rollback_mars1057.sql"
|
|||||||
7z a -pMojeSuperHaslo#123 -mhe=on M1057_arch.7z MARS-1057
|
7z a -pMojeSuperHaslo#123 -mhe=on M1057_arch.7z MARS-1057
|
||||||
|
|
||||||
|
|
||||||
|
cd .\MARS_Packages\REL01_ADDITIONS\MARS-828
|
||||||
|
echo 'yes' | sql "ADMIN/Cloudpass#34@ggmichalski_high" "@install_mars828.sql"
|
||||||
|
echo 'yes' | sql "ADMIN/Cloudpass#34@ggmichalski_high" "@rollback_mars828.sql"
|
||||||
|
7z a -pMojeSuperHaslo#123 -mhe=on M828_arch.7z MARS-828\
|
||||||
|
|
||||||
|
|
||||||
cd .\MARS_Packages\REL02_POST\MARS-956
|
cd .\MARS_Packages\REL02_POST\MARS-956
|
||||||
echo 'yes' | sql "ADMIN/Cloudpass#34@ggmichalski_high" "@install_mars956.sql"
|
echo 'yes' | sql "ADMIN/Cloudpass#34@ggmichalski_high" "@install_mars956.sql"
|
||||||
echo 'yes' | sql "ADMIN/Cloudpass#34@ggmichalski_high" "@rollback_mars956.sql"
|
echo 'yes' | sql "ADMIN/Cloudpass#34@ggmichalski_high" "@rollback_mars956.sql"
|
||||||
|
|||||||
682
confluence/FILE_ARCHIVER_Guide.md
Normal file
682
confluence/FILE_ARCHIVER_Guide.md
Normal file
@@ -0,0 +1,682 @@
|
|||||||
|
# FILE_ARCHIVER Configuration Guide
|
||||||
|
|
||||||
|
This document describes the archival strategies available in the FILE_ARCHIVER package for managing data lifecycle across OCI buckets (INBOX → ODS → ARCHIVE).
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The FILE_ARCHIVER package provides flexible archival strategies that accommodate different data retention policies across source systems. It manages the movement of processed data from operational storage (ODS bucket) to long-term archival storage (ARCHIVE bucket) based on configurable strategies.
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
|
||||||
|
- **Three Archival Strategies**: THRESHOLD_BASED, MINIMUM_AGE_MONTHS (with 0=current month only), HYBRID
|
||||||
|
- **Flexible Configuration**: Per-table archival strategy configuration via A_SOURCE_FILE_CONFIG
|
||||||
|
- **Backward Compatible**: Default THRESHOLD_BASED strategy maintains existing behavior
|
||||||
|
- **Validation**: Automatic validation of strategy-specific configuration requirements
|
||||||
|
- **OCI Integration**: Works seamlessly with DBMS_CLOUD operations via cloud_wrapper
|
||||||
|
|
||||||
|
### Package Information
|
||||||
|
|
||||||
|
- **Schema**: CT_MRDS
|
||||||
|
- **Package**: FILE_ARCHIVER
|
||||||
|
- **Current Version**: 3.2.0
|
||||||
|
- **Dependencies**: ENV_MANAGER, FILE_MANAGER, cloud_wrapper, A_SOURCE_FILE_CONFIG, A_SOURCE_FILE_RECEIVED, A_WORKFLOW_HISTORY
|
||||||
|
|
||||||
|
### Critical Prerequisites
|
||||||
|
|
||||||
|
⚠️ **IMPORTANT**: FILE_ARCHIVER requires data to be registered in `CT_MRDS.A_SOURCE_FILE_RECEIVED` table. This table is automatically populated when files are processed through the modern Airflow + DBT workflow via `FILE_MANAGER.PROCESS_SOURCE_FILE`.
|
||||||
|
|
||||||
|
**For legacy data migrated from Informatica + WLA system:**
|
||||||
|
- Legacy data exported using `DATA_EXPORTER` does NOT automatically create `A_SOURCE_FILE_RECEIVED` records
|
||||||
|
- Without these records, FILE_ARCHIVER **CANNOT** archive the data
|
||||||
|
- See [System Migration Guide](System_Migration_Informatica_to_Airflow_DBT.md) for workaround strategies
|
||||||
|
|
||||||
|
**Recommendation for legacy data**: Export directly to ARCHIVE bucket using `DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE` with `pBucketArea => 'ARCHIVE'` to bypass this requirement
|
||||||
|
|
||||||
|
## Archival Strategies
|
||||||
|
|
||||||
|
### Strategy Overview
|
||||||
|
|
||||||
|
| Strategy | WHERE Clause Logic | Configuration Required | Primary Use Case |
|
||||||
|
|----------|-------------------|----------------------|------------------|
|
||||||
|
| `THRESHOLD_BASED` | Days since workflow start > threshold | DAYS_FOR_ARCHIVE_THRESHOLD | Legacy compatibility, simple time-based archival |
|
||||||
|
| `MINIMUM_AGE_MONTHS` | Archive data older than X months (0=current month only) | MINIMUM_AGE_MONTHS (≥0) | All sources - flexible retention (0 for LM, 6 for CSDB) |
|
||||||
|
| `HYBRID` | Combines month boundary + minimum age | MINIMUM_AGE_MONTHS | Advanced retention scenarios |
|
||||||
|
|
||||||
|
### 1. THRESHOLD_BASED (Default)
|
||||||
|
|
||||||
|
Archives data based on number of days since workflow start.
|
||||||
|
|
||||||
|
**WHERE Clause**:
|
||||||
|
```sql
|
||||||
|
extract(day from (systimestamp - workflow_start)) > DAYS_FOR_ARCHIVE_THRESHOLD
|
||||||
|
```
|
||||||
|
|
||||||
|
**Configuration**:
|
||||||
|
```sql
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'THRESHOLD_BASED',
|
||||||
|
DAYS_FOR_ARCHIVE_THRESHOLD = 30,
|
||||||
|
MINIMUM_AGE_MONTHS = NULL
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND SOURCE_FILE_ID = 'C2D_DATA'
|
||||||
|
AND TABLE_ID = 'C2D_TABLE';
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Case**: Simple time-based archival, backward compatible with FILE_ARCHIVER v2.0.0 behavior.
|
||||||
|
|
||||||
|
### 2. MINIMUM_AGE_MONTHS
|
||||||
|
|
||||||
|
Archives data older than specified number of months. **Special case**: MINIMUM_AGE_MONTHS = 0 archives all data before current month (replaces deprecated CURRENT_MONTH_ONLY strategy).
|
||||||
|
|
||||||
|
**WHERE Clause**:
|
||||||
|
```sql
|
||||||
|
workflow_start < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -MINIMUM_AGE_MONTHS)
|
||||||
|
-- When MINIMUM_AGE_MONTHS = 0: workflow_start < TRUNC(SYSDATE, 'MM')
|
||||||
|
```
|
||||||
|
|
||||||
|
**Configuration Examples**:
|
||||||
|
```sql
|
||||||
|
-- LM: Keep only current month data (MINIMUM_AGE_MONTHS = 0)
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 0
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND SOURCE_FILE_ID = 'DistributeStandingFacilities'
|
||||||
|
AND TABLE_ID = 'LM_STANDING_FACILITIES';
|
||||||
|
|
||||||
|
-- CSDB: Retain 6 months of data (MINIMUM_AGE_MONTHS = 6)
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 6
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND SOURCE_FILE_ID = 'CSDB'
|
||||||
|
AND TABLE_ID IN ('CSDB_DEBT', 'CSDB_DEBT_DAILY');
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Cases**:
|
||||||
|
- **MINIMUM_AGE_MONTHS = 0**: LM dissemination feeds requiring current month only (daily/intraday updates)
|
||||||
|
- **MINIMUM_AGE_MONTHS = 6**: CSDB securities/ratings data requiring 6-month retention
|
||||||
|
- **MINIMUM_AGE_MONTHS = N**: Regulatory compliance with specific N-month retention periods
|
||||||
|
|
||||||
|
**Behavior Examples**:
|
||||||
|
- **With MINIMUM_AGE_MONTHS = 0**:
|
||||||
|
- January data: Archived on February 1st
|
||||||
|
- February data: Remains in ODS bucket during February
|
||||||
|
- March 1st: February data archived, March data active
|
||||||
|
|
||||||
|
- **With MINIMUM_AGE_MONTHS = 6**:
|
||||||
|
- February 2026: Archives data from July 2025 and earlier
|
||||||
|
- March 2026: Archives data from August 2025 and earlier
|
||||||
|
- Keeps current month + 6 previous months (7 months total) in ODS bucket
|
||||||
|
|
||||||
|
### 3. HYBRID
|
||||||
|
|
||||||
|
Combines month boundary check with minimum age threshold - archives data from previous months AND older than minimum age.
|
||||||
|
|
||||||
|
**WHERE Clause**:
|
||||||
|
```sql
|
||||||
|
TRUNC(workflow_start, 'MM') < TRUNC(SYSDATE, 'MM')
|
||||||
|
AND workflow_start < ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -MINIMUM_AGE_MONTHS)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Configuration**:
|
||||||
|
```sql
|
||||||
|
-- Advanced: Current month + 3 months minimum
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'HYBRID',
|
||||||
|
MINIMUM_AGE_MONTHS = 3
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND SOURCE_FILE_ID = 'SPECIAL_SOURCE'
|
||||||
|
AND TABLE_ID = 'SPECIAL_TABLE';
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Case**: Advanced scenarios requiring both current month retention AND minimum age threshold.
|
||||||
|
|
||||||
|
## Configuration Validation
|
||||||
|
|
||||||
|
### Validation Trigger
|
||||||
|
|
||||||
|
**Trigger**: `TRG_BI_A_SRC_FILE_CFG_ARCH_VAL`
|
||||||
|
|
||||||
|
Automatically validates archival configuration on INSERT/UPDATE to A_SOURCE_FILE_CONFIG:
|
||||||
|
|
||||||
|
**Validation Rules**:
|
||||||
|
1. **MINIMUM_AGE_MONTHS**: Requires `MINIMUM_AGE_MONTHS IS NOT NULL AND MINIMUM_AGE_MONTHS >= 0`
|
||||||
|
- Error: "Strategy MINIMUM_AGE_MONTHS requires MINIMUM_AGE_MONTHS to be set (≥0)"
|
||||||
|
|
||||||
|
2. **HYBRID**: Requires `MINIMUM_AGE_MONTHS IS NOT NULL`
|
||||||
|
- Error: "Strategy HYBRID requires MINIMUM_AGE_MONTHS to be set"
|
||||||
|
|
||||||
|
**Example Validation Error**:
|
||||||
|
```sql
|
||||||
|
-- This will fail validation
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = NULL -- ERROR: Required for this strategy
|
||||||
|
WHERE ...;
|
||||||
|
|
||||||
|
-- Error: ORA-20001: Strategy MINIMUM_AGE_MONTHS requires MINIMUM_AGE_MONTHS to be set
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Lifecycle Workflow
|
||||||
|
|
||||||
|
### Standard File Processing Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ FILE PROCESSING LIFECYCLE │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
1. INBOX Bucket (Validation)
|
||||||
|
├─ File arrives from source system
|
||||||
|
├─ FILE_MANAGER.PROCESS_SOURCE_FILE validates structure
|
||||||
|
├─ Status: RECEIVED → VALIDATED → READY_FOR_INGESTION
|
||||||
|
└─ FILE_MANAGER.MOVE_FILE relocates to ODS bucket
|
||||||
|
|
||||||
|
2. ODS Bucket (Operational Data)
|
||||||
|
├─ Active data processing (Airflow + DBT)
|
||||||
|
├─ External tables read data from bucket
|
||||||
|
├─ Status: INGESTED
|
||||||
|
├─ FILE_ARCHIVER.ARCHIVE_TABLE_DATA archives based on strategy
|
||||||
|
└─ CSV files moved to TRASH subfolder (ODS → TRASH/)
|
||||||
|
|
||||||
|
2.1 TRASH Subfolder (DATA Bucket - File Retention)
|
||||||
|
├─ Located in DATA bucket (e.g., TRASH/LM/TABLE_NAME)
|
||||||
|
├─ Stores CSV files after archival to Parquet
|
||||||
|
├─ Status: ARCHIVED_AND_TRASHED (default retention)
|
||||||
|
├─ Enables rollback if archival issues occur
|
||||||
|
└─ Optional cleanup: ARCHIVED_AND_PURGED (pKeepInTrash=FALSE)
|
||||||
|
|
||||||
|
3. ARCHIVE Bucket (Long-term Storage)
|
||||||
|
├─ Historical data in Parquet format
|
||||||
|
├─ Hive-style partitioning: PARTITION_YEAR=/PARTITION_MONTH=
|
||||||
|
├─ Status: ARCHIVED_AND_TRASHED or ARCHIVED_AND_PURGED
|
||||||
|
└─ Optimized for big data analytics (Spark, Hive)
|
||||||
|
|
||||||
|
**Key Procedures**:
|
||||||
|
- `ARCHIVE_TABLE_DATA(pSourceFileConfigKey, pKeepInTrash)` - Main archival procedure using strategy-specific WHERE clause
|
||||||
|
- `pKeepInTrash` (BOOLEAN, DEFAULT TRUE) - Controls TRASH folder retention
|
||||||
|
- TRUE: Files kept in TRASH folder for safety and rollback capability (default)
|
||||||
|
- FALSE: Files deleted from TRASH folder after successful archival
|
||||||
|
- `GET_ARCHIVAL_WHERE_CLAUSE` - Returns WHERE clause based on configured strategy
|
||||||
|
- `GATHER_TABLE_STAT` - Calculates archival statistics using strategy logic
|
||||||
|
|
||||||
|
**Archival Execution**:
|
||||||
|
```sql
|
||||||
|
-- Default behavior: Keep files in TRASH folder (ARCHIVED_AND_TRASHED status)
|
||||||
|
BEGIN
|
||||||
|
CT_MRDS.FILE_ARCHIVER.ARCHIVE_TABLE_DATA(
|
||||||
|
pSourceFileConfigKey => vSourceFileConfigKey,
|
||||||
|
pKeepInTrash => TRUE -- DEFAULT value
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
-- Optional: Delete files from TRASH after archival (ARCHIVED_AND_PURGED status)
|
||||||
|
BEGIN
|
||||||
|
CT_MRDS.FILE_ARCHIVER.ARCHIVE_TABLE_DATA(
|
||||||
|
pSourceFileConfigKey => vSourceFileConfigKey,
|
||||||
|
pKeepInTrash => FALSE -- Cleanup TRASH folder
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Strategy-Based Filtering**:
|
||||||
|
- Package retrieves ARCHIVAL_STRATEGY from A_SOURCE_FILE_CONFIG
|
||||||
|
- GET_ARCHIVAL_WHERE_CLAUSE generates appropriate WHERE clause
|
||||||
|
- Data matching criteria moved from ODS to ARCHIVE bucket
|
||||||
|
- CSV files moved to TRASH subfolder in DATA bucket (ODS/ → TRASH/)
|
||||||
|
- Parquet format with Hive-style partitioning applied to ARCHIVE bucket
|
||||||
|
- TRASH retention controlled by pKeepInTrash parameter
|
||||||
|
|
||||||
|
## Configuration Examples
|
||||||
|
|
||||||
|
### Example 1: Configure LM Standing Facilities (Current Month Only)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Keep only current month data in ODS bucket (MINIMUM_AGE_MONTHS = 0)
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 0 -- 0 = archives all data before current month
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND SOURCE_FILE_ID = 'DistributeStandingFacilities'
|
||||||
|
AND TABLE_ID = 'LM_STANDING_FACILITIES';
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
-- Verify configuration
|
||||||
|
SELECT
|
||||||
|
SOURCE_FILE_ID,
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_ID = 'DistributeStandingFacilities';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2: Configure CSDB Debt (MINIMUM_AGE_MONTHS)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Retain 6 months of data in ODS bucket
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 6
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND SOURCE_FILE_ID = 'CSDB'
|
||||||
|
AND TABLE_ID = 'CSDB_DEBT';
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
-- Verify configuration
|
||||||
|
SELECT
|
||||||
|
SOURCE_FILE_ID,
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE TABLE_ID = 'CSDB_DEBT';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 3: Bulk Configuration for LM Source
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Configure all 19 LM tables with MINIMUM_AGE_MONTHS = 0 (current month only)
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 0 -- 0 = keep only current month
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND SOURCE_FILE_ID IN (
|
||||||
|
'DistributeStandingFacilities',
|
||||||
|
'DistributeTTS',
|
||||||
|
'DistributeAdHocAdjustments',
|
||||||
|
'DistributeBalanceSheet',
|
||||||
|
'DistributeCSMAdjustments',
|
||||||
|
'DistributeCurrentAccounts',
|
||||||
|
'DistributeForecast',
|
||||||
|
'DistributeQREAdjustments'
|
||||||
|
);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
-- Verify bulk configuration
|
||||||
|
SELECT
|
||||||
|
SOURCE_FILE_ID,
|
||||||
|
COUNT(*) AS TABLE_COUNT,
|
||||||
|
MAX(ARCHIVAL_STRATEGY) AS STRATEGY,
|
||||||
|
MAX(MINIMUM_AGE_MONTHS) AS MIN_AGE
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_ID LIKE 'Distribute%'
|
||||||
|
GROUP BY SOURCE_FILE_ID
|
||||||
|
ORDER BY SOURCE_FILE_ID;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 4: View Current Archival Configuration
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- All configured tables with their archival strategies
|
||||||
|
SELECT
|
||||||
|
A_SOURCE_KEY,
|
||||||
|
SOURCE_FILE_ID,
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
DAYS_FOR_ARCHIVE_THRESHOLD
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
ORDER BY A_SOURCE_KEY, SOURCE_FILE_ID, TABLE_ID;
|
||||||
|
|
||||||
|
-- Summary by strategy
|
||||||
|
SELECT
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
COUNT(*) AS TABLE_COUNT,
|
||||||
|
MIN(MINIMUM_AGE_MONTHS) AS MIN_AGE_MIN,
|
||||||
|
MAX(MINIMUM_AGE_MONTHS) AS MIN_AGE_MAX
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
GROUP BY ARCHIVAL_STRATEGY
|
||||||
|
ORDER BY ARCHIVAL_STRATEGY;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Release 01 Configuration
|
||||||
|
|
||||||
|
### Configured Tables (MARS-828)
|
||||||
|
|
||||||
|
The following 25 Release 01 tables were configured with archival strategies:
|
||||||
|
|
||||||
|
**LM Tables (19 total) - MINIMUM_AGE_MONTHS = 0 (current month only)**:
|
||||||
|
- 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
|
||||||
|
|
||||||
|
**CSDB Tables (6 total)**:
|
||||||
|
|
||||||
|
*MINIMUM_AGE_MONTHS = 6 (6-month retention)*:
|
||||||
|
- CSDB_DEBT
|
||||||
|
- CSDB_DEBT_DAILY
|
||||||
|
|
||||||
|
*MINIMUM_AGE_MONTHS = 0 (current month only)*:
|
||||||
|
- CSDB_INSTR_RAT_FULL
|
||||||
|
- CSDB_INSTR_DESC_FULL
|
||||||
|
- CSDB_ISSUER_RAT_FULL
|
||||||
|
- CSDB_ISSUER_DESC_FULL
|
||||||
|
|
||||||
|
**Verification Query**:
|
||||||
|
```sql
|
||||||
|
-- Check Release 01 configuration
|
||||||
|
SELECT
|
||||||
|
CASE
|
||||||
|
WHEN TABLE_ID LIKE 'LM_%' THEN 'LM'
|
||||||
|
WHEN TABLE_ID LIKE 'CSDB_%' THEN 'CSDB'
|
||||||
|
END AS SOURCE_GROUP,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
COUNT(*) AS TABLE_COUNT
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_TYPE = 'INPUT'
|
||||||
|
AND TABLE_ID IN (
|
||||||
|
-- 25 Release 01 tables
|
||||||
|
'LM_STANDING_FACILITIES', 'LM_STANDING_FACILITIES_HEADER',
|
||||||
|
'LM_TTS_HEADER', 'LM_TTS_ITEM',
|
||||||
|
-- ... other tables
|
||||||
|
)
|
||||||
|
GROUP BY
|
||||||
|
CASE
|
||||||
|
WHEN TABLE_ID LIKE 'LM_%' THEN 'LM'
|
||||||
|
WHEN TABLE_ID LIKE 'CSDB_%' THEN 'CSDB'
|
||||||
|
END,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS
|
||||||
|
ORDER BY SOURCE_GROUP, ARCHIVAL_STRATEGY;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
#### Issue 1: Validation Error on Configuration Update
|
||||||
|
|
||||||
|
**Error**:
|
||||||
|
```
|
||||||
|
ORA-20001: Strategy MINIMUM_AGE_MONTHS requires MINIMUM_AGE_MONTHS to be set
|
||||||
|
```
|
||||||
|
|
||||||
|
**Cause**: Trigger validation failed - strategy requires MINIMUM_AGE_MONTHS but value is NULL
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```sql
|
||||||
|
-- Provide required MINIMUM_AGE_MONTHS value
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 6 -- Required for this strategy
|
||||||
|
WHERE ...;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Issue 2: Archival Not Working as Expected
|
||||||
|
|
||||||
|
**Symptoms**: Data not being archived according to strategy
|
||||||
|
|
||||||
|
**Diagnostic Steps**:
|
||||||
|
```sql
|
||||||
|
-- 1. Check configuration
|
||||||
|
SELECT
|
||||||
|
SOURCE_FILE_ID,
|
||||||
|
TABLE_ID,
|
||||||
|
ARCHIVAL_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS,
|
||||||
|
DAYS_FOR_ARCHIVE_THRESHOLD
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE TABLE_ID = 'YOUR_TABLE';
|
||||||
|
|
||||||
|
-- 2. Check package version
|
||||||
|
SELECT CT_MRDS.FILE_ARCHIVER.GET_VERSION() FROM DUAL;
|
||||||
|
-- Expected: 3.0.0 or higher
|
||||||
|
|
||||||
|
-- 3. Check process logs
|
||||||
|
SELECT
|
||||||
|
PROCESS_LOG_KEY,
|
||||||
|
PROCESS_NAME,
|
||||||
|
LOG_MESSAGE,
|
||||||
|
LOG_LEVEL,
|
||||||
|
LOG_TIMESTAMP
|
||||||
|
FROM CT_MRDS.A_PROCESS_LOG
|
||||||
|
WHERE PROCESS_NAME LIKE '%ARCHIVE%'
|
||||||
|
ORDER BY LOG_TIMESTAMP DESC
|
||||||
|
FETCH FIRST 20 ROWS ONLY;
|
||||||
|
|
||||||
|
-- 4. Test WHERE clause generation
|
||||||
|
DECLARE
|
||||||
|
vConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE;
|
||||||
|
vWhereClause VARCHAR2(4000);
|
||||||
|
BEGIN
|
||||||
|
SELECT * INTO vConfig
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE TABLE_ID = 'YOUR_TABLE'
|
||||||
|
AND ROWNUM = 1;
|
||||||
|
|
||||||
|
vWhereClause := CT_MRDS.FILE_ARCHIVER.GET_ARCHIVAL_WHERE_CLAUSE(vConfig);
|
||||||
|
DBMS_OUTPUT.PUT_LINE('WHERE Clause: ' || vWhereClause);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Issue 3: Package Compilation Errors After Upgrade
|
||||||
|
|
||||||
|
**Symptoms**: FILE_ARCHIVER package shows INVALID status
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```sql
|
||||||
|
-- Check compilation errors
|
||||||
|
SELECT * FROM USER_ERRORS
|
||||||
|
WHERE NAME = 'FILE_ARCHIVER'
|
||||||
|
AND TYPE IN ('PACKAGE', 'PACKAGE BODY')
|
||||||
|
ORDER BY SEQUENCE;
|
||||||
|
|
||||||
|
-- Recompile package
|
||||||
|
ALTER PACKAGE CT_MRDS.FILE_ARCHIVER COMPILE SPECIFICATION;
|
||||||
|
ALTER PACKAGE CT_MRDS.FILE_ARCHIVER COMPILE BODY;
|
||||||
|
|
||||||
|
-- Verify status
|
||||||
|
SELECT object_name, object_type, status
|
||||||
|
FROM user_objects
|
||||||
|
WHERE object_name = 'FILE_ARCHIVER';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Version History
|
||||||
|
|
||||||
|
### v3.1.0 (Current - 2026-02-05)
|
||||||
|
- **BREAKING CHANGE**: Removed CURRENT_MONTH_ONLY strategy (replaced by MINIMUM_AGE_MONTHS = 0)
|
||||||
|
- Mathematical equivalence: CURRENT_MONTH_ONLY ≡ MINIMUM_AGE_MONTHS = 0
|
||||||
|
- Updated trigger validation to allow MINIMUM_AGE_MONTHS >= 0 (previously >= 1)
|
||||||
|
- Simplified architecture from 4 strategies to 3
|
||||||
|
- Enhanced error handling
|
||||||
|
- All 25 Release 01 tables migrated to MINIMUM_AGE_MONTHS (23 with value 0, 2 with value 6)
|
||||||
|
|
||||||
|
### v3.0.0 (MARS-828 - 2026-02-04)
|
||||||
|
- Added ARCHIVAL_STRATEGY configuration column
|
||||||
|
- Implemented four archival strategies (later reduced to three in v3.1.0):
|
||||||
|
- THRESHOLD_BASED (backward compatible)
|
||||||
|
- CURRENT_MONTH_ONLY (deprecated in v3.1.0, use MINIMUM_AGE_MONTHS = 0)
|
||||||
|
- MINIMUM_AGE_MONTHS
|
||||||
|
- HYBRID
|
||||||
|
- Added GET_ARCHIVAL_WHERE_CLAUSE function
|
||||||
|
- Created validation trigger TRG_BI_A_SRC_FILE_CFG_ARCH_VAL
|
||||||
|
- Configured 25 Release 01 tables with appropriate strategies
|
||||||
|
|
||||||
|
### v2.0.0 (Legacy)
|
||||||
|
- Initial FILE_ARCHIVER package
|
||||||
|
- THRESHOLD_BASED archival only
|
||||||
|
- Fixed DAYS_FOR_ARCHIVE_THRESHOLD configuration
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
- [FILE_MANAGER Configuration Guide](FILE_MANAGER_Configuration_Guide.md) - File processing and validation
|
||||||
|
- [Package Deployment Guide](Package_Deployment_Guide.md) - Package deployment standards
|
||||||
|
- [Universal Package Tracking System](Universal_Package_Tracking_System.md) - Version tracking
|
||||||
|
- [MARS-828 README](../MARS_Packages/REL01_ADDITIONS/MARS-828/README.md) - Detailed implementation notes
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
### Required Packages
|
||||||
|
- **CT_MRDS.ENV_MANAGER** v3.x - Error handling, logging, version tracking
|
||||||
|
- **CT_MRDS.FILE_MANAGER** v3.x - Bucket URI resolution, file processing
|
||||||
|
- **MRDS_LOADER.cloud_wrapper** - DBMS_CLOUD operations wrapper
|
||||||
|
|
||||||
|
### Database Objects
|
||||||
|
- **Table**: CT_MRDS.A_SOURCE_FILE_CONFIG - Configuration storage
|
||||||
|
- **Table**: CT_MRDS.A_SOURCE_FILE_RECEIVED - File processing tracking
|
||||||
|
- **Table**: CT_MRDS.A_WORKFLOW_HISTORY - Workflow execution tracking (Airflow + DBT)
|
||||||
|
- **Trigger**: TRG_BI_A_SRC_FILE_CFG_ARCH_VAL - Configuration validation
|
||||||
|
- **Credential**: DEF_CRED_ARN - OCI bucket access
|
||||||
|
|
||||||
|
### OCI Buckets
|
||||||
|
- **INBOX**: Incoming file validation (`'INBOX/{SOURCE}/{SOURCE_FILE_ID}/{TABLE_NAME}/'`)
|
||||||
|
- **ODS/DATA**: Operational data processing (`'ODS/{SOURCE}/{TABLE_NAME}/'`)
|
||||||
|
- **TRASH**: File retention subfolder in DATA bucket (`'TRASH/{SOURCE}/{TABLE_NAME}/'`) - CSV files after archival
|
||||||
|
- **ARCHIVE**: Historical data storage (`'ARCHIVE/{SOURCE}/{TABLE_NAME}/PARTITION_YEAR=/PARTITION_MONTH=/'`)
|
||||||
|
|
||||||
|
**Note**: TRASH is NOT a separate bucket - it's a subfolder within the DATA bucket for file retention and rollback capability.
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### Strategy Selection Guidelines
|
||||||
|
|
||||||
|
1. **Use MINIMUM_AGE_MONTHS when**:
|
||||||
|
- **MINIMUM_AGE_MONTHS = 0**: Current month only retention
|
||||||
|
- Data updated frequently (daily/intraday)
|
||||||
|
- Historical data access is rare
|
||||||
|
- ODS bucket space is limited
|
||||||
|
- Example: LM dissemination feeds
|
||||||
|
- **MINIMUM_AGE_MONTHS = N (N > 0)**: Multi-month retention
|
||||||
|
- Regulatory compliance requires specific retention period
|
||||||
|
- Analytical workloads need N-month access
|
||||||
|
- Data updates are infrequent
|
||||||
|
- Example: CSDB securities data (MINIMUM_AGE_MONTHS = 6)
|
||||||
|
|
||||||
|
2. **Use THRESHOLD_BASED when**:
|
||||||
|
- Maintaining backward compatibility with legacy behavior
|
||||||
|
- Simple time-based archival is sufficient
|
||||||
|
- Migration from FILE_ARCHIVER v2.0.0
|
||||||
|
|
||||||
|
3. **Use HYBRID when**:
|
||||||
|
- Complex retention requirements
|
||||||
|
- Combining month boundary check with minimum age threshold
|
||||||
|
- Advanced scenarios not covered by other strategies
|
||||||
|
|
||||||
|
### Configuration Best Practices
|
||||||
|
|
||||||
|
1. **Test Configuration Changes**:
|
||||||
|
```sql
|
||||||
|
-- Test on single table first
|
||||||
|
UPDATE CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
SET ARCHIVAL_STRATEGY = 'MINIMUM_AGE_MONTHS',
|
||||||
|
MINIMUM_AGE_MONTHS = 0 -- 0 = current month only
|
||||||
|
WHERE SOURCE_FILE_ID = 'TEST_FILE'
|
||||||
|
AND TABLE_ID = 'TEST_TABLE';
|
||||||
|
|
||||||
|
-- Monitor archival behavior
|
||||||
|
-- Expand to other tables after validation
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Verify Before Bulk Updates**:
|
||||||
|
```sql
|
||||||
|
-- Preview changes with SELECT
|
||||||
|
SELECT
|
||||||
|
SOURCE_FILE_ID,
|
||||||
|
TABLE_ID,
|
||||||
|
'MINIMUM_AGE_MONTHS' AS NEW_STRATEGY,
|
||||||
|
0 AS NEW_MIN_AGE, -- 0 = current month only
|
||||||
|
ARCHIVAL_STRATEGY AS OLD_STRATEGY,
|
||||||
|
MINIMUM_AGE_MONTHS AS OLD_MIN_AGE
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_ID LIKE 'Distribute%';
|
||||||
|
|
||||||
|
-- Then execute UPDATE
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Document Configuration Decisions**:
|
||||||
|
- Record why specific strategy was chosen
|
||||||
|
- Note business requirements driving retention policy
|
||||||
|
- Track configuration changes in version control
|
||||||
|
|
||||||
|
4. **Monitor Archival Performance**:
|
||||||
|
```sql
|
||||||
|
-- Check archival execution logs
|
||||||
|
SELECT
|
||||||
|
PROCESS_NAME,
|
||||||
|
LOG_MESSAGE,
|
||||||
|
LOG_TIMESTAMP
|
||||||
|
FROM CT_MRDS.A_PROCESS_LOG
|
||||||
|
WHERE PROCESS_NAME LIKE '%ARCHIVE%'
|
||||||
|
AND LOG_TIMESTAMP > SYSDATE - 7
|
||||||
|
ORDER BY LOG_TIMESTAMP DESC;
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Regular Configuration Reviews**:
|
||||||
|
- Verify strategies still match business requirements
|
||||||
|
- Check for tables without archival configuration
|
||||||
|
- Optimize MINIMUM_AGE_MONTHS based on actual usage patterns
|
||||||
|
|
||||||
|
### TRASH Folder Retention Best Practices
|
||||||
|
|
||||||
|
1. **Default Behavior (pKeepInTrash = TRUE - Recommended)**:
|
||||||
|
- Keeps CSV files in TRASH folder after archival
|
||||||
|
- Provides safety net for rollback if archival issues occur
|
||||||
|
- Supports compliance and audit requirements
|
||||||
|
- Status: ARCHIVED_AND_TRASHED
|
||||||
|
- Use for: Production environments, regulatory compliance, critical data
|
||||||
|
|
||||||
|
2. **TRASH Cleanup (pKeepInTrash = FALSE)**:
|
||||||
|
- Deletes CSV files from TRASH folder after successful archival
|
||||||
|
- Reduces storage costs in DATA bucket
|
||||||
|
- Status: ARCHIVED_AND_PURGED
|
||||||
|
- Use for: Non-critical data, storage optimization, test environments
|
||||||
|
|
||||||
|
3. **Monitoring TRASH Folder**:
|
||||||
|
```sql
|
||||||
|
-- Check files in TRASH retention
|
||||||
|
SELECT
|
||||||
|
SOURCE_FILE_NAME,
|
||||||
|
PROCESSING_STATUS,
|
||||||
|
ARCH_FILE_NAME,
|
||||||
|
PARTITION_YEAR,
|
||||||
|
PARTITION_MONTH
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_RECEIVED
|
||||||
|
WHERE PROCESSING_STATUS IN ('ARCHIVED_AND_TRASHED', 'ARCHIVED_AND_PURGED')
|
||||||
|
AND RECEPTION_DATE > SYSDATE - 30
|
||||||
|
ORDER BY PROCESSING_STATUS, RECEPTION_DATE DESC;
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **TRASH Folder Structure**:
|
||||||
|
```
|
||||||
|
DATA Bucket:
|
||||||
|
├── ODS/LM/STANDING_FACILITIES/file.csv -- Active operational data
|
||||||
|
└── TRASH/LM/STANDING_FACILITIES/file.csv -- Retained after archival
|
||||||
|
|
||||||
|
ARCHIVE Bucket:
|
||||||
|
└── ARCHIVE/LM/STANDING_FACILITIES/
|
||||||
|
└── PARTITION_YEAR=2026/
|
||||||
|
└── PARTITION_MONTH=02/
|
||||||
|
└── *.parquet -- Archived data
|
||||||
|
```
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
Created by: Grzegorz Michalski
|
||||||
|
Date: 2026-02-06
|
||||||
|
Schema: CT_MRDS
|
||||||
|
Package: FILE_ARCHIVER
|
||||||
|
Version: 3.2.0
|
||||||
@@ -371,11 +371,14 @@ INBOX Bucket - Pattern: 'INBOX/{SOURCE}/{SOURCE_FILE_ID}/{TABLE_NAME}/'
|
|||||||
└── {pTableId}/ -- e.g., "A_UC_DISSEM_METADATA_LOADS", "STANDING_FACILITIES"
|
└── {pTableId}/ -- e.g., "A_UC_DISSEM_METADATA_LOADS", "STANDING_FACILITIES"
|
||||||
└── files matching {pSourceFileNamePattern}
|
└── files matching {pSourceFileNamePattern}
|
||||||
|
|
||||||
ODS Bucket - Pattern: 'ODS/{SOURCE}/{TABLE_NAME}/'
|
DATA Bucket - Patterns: 'ODS/{SOURCE}/{TABLE_NAME}/' and 'TRASH/{SOURCE}/{TABLE_NAME}/'
|
||||||
└── ODS/
|
├── ODS/
|
||||||
|
│ └── {pSourceKey}/ -- e.g., "C2D", "LM"
|
||||||
|
│ └── {pTableId}/ -- e.g., "A_UC_DISSEM_METADATA_LOADS", "STANDING_FACILITIES"
|
||||||
|
│ └── processed files
|
||||||
|
└── TRASH/ -- File retention subfolder (not a separate bucket)
|
||||||
└── {pSourceKey}/ -- e.g., "C2D", "LM"
|
└── {pSourceKey}/ -- e.g., "C2D", "LM"
|
||||||
└── {pTableId}/ -- e.g., "A_UC_DISSEM_METADATA_LOADS", "STANDING_FACILITIES"
|
└── {pTableId}/ -- CSV files after archival (ARCHIVED_AND_TRASHED status)
|
||||||
└── processed files
|
|
||||||
|
|
||||||
ARCHIVE Bucket - Pattern: 'ARCHIVE/{SOURCE}/{TABLE_NAME}/'
|
ARCHIVE Bucket - Pattern: 'ARCHIVE/{SOURCE}/{TABLE_NAME}/'
|
||||||
└── ARCHIVE/
|
└── ARCHIVE/
|
||||||
@@ -389,9 +392,11 @@ ARCHIVE Bucket - Pattern: 'ARCHIVE/{SOURCE}/{TABLE_NAME}/'
|
|||||||
**Critical Path Pattern Requirements:**
|
**Critical Path Pattern Requirements:**
|
||||||
- **INBOX** requires full 3-level path: `INBOX/{SOURCE}/{SOURCE_FILE_ID}/{TABLE_NAME}/`
|
- **INBOX** requires full 3-level path: `INBOX/{SOURCE}/{SOURCE_FILE_ID}/{TABLE_NAME}/`
|
||||||
- **ODS** uses simplified 2-level path: `ODS/{SOURCE}/{TABLE_NAME}/` (no SOURCE_FILE_ID)
|
- **ODS** uses simplified 2-level path: `ODS/{SOURCE}/{TABLE_NAME}/` (no SOURCE_FILE_ID)
|
||||||
|
- **TRASH** uses simplified 2-level path: `TRASH/{SOURCE}/{TABLE_NAME}/` (subfolder in DATA bucket)
|
||||||
- **ARCHIVE** uses simplified 2-level path: `ARCHIVE/{SOURCE}/{TABLE_NAME}/` (no SOURCE_FILE_ID)
|
- **ARCHIVE** uses simplified 2-level path: `ARCHIVE/{SOURCE}/{TABLE_NAME}/` (no SOURCE_FILE_ID)
|
||||||
- **All patterns are mandatory** - no simplified versions allowed
|
- **All patterns are mandatory** - no simplified versions allowed
|
||||||
- File names must match `pSourceFileNamePattern` for automatic processing
|
- File names must match `pSourceFileNamePattern` for automatic processing
|
||||||
|
- **Note**: TRASH is NOT a separate bucket - it's a subfolder within the DATA bucket
|
||||||
|
|
||||||
## Configuration Management Best Practices
|
## Configuration Management Best Practices
|
||||||
|
|
||||||
@@ -693,7 +698,10 @@ SELECT FILE_MANAGER.PROCESS_SOURCE_FILE(
|
|||||||
|
|
||||||
1. **File Arrival**: File is uploaded to Oracle Cloud Storage bucket
|
1. **File Arrival**: File is uploaded to Oracle Cloud Storage bucket
|
||||||
2. **Registration**: FILE_MANAGER.REGISTER_SOURCE_FILE_RECEIVED() creates record
|
2. **Registration**: FILE_MANAGER.REGISTER_SOURCE_FILE_RECEIVED() creates record
|
||||||
3. **Status**: RECEIVED → VALIDATED → READY_FOR_INGESTION → INGESTED → ARCHIVED
|
3. **Status**: RECEIVED → VALIDATED → READY_FOR_INGESTION → INGESTED → ARCHIVED_AND_TRASHED → ARCHIVED_AND_PURGED (optional)
|
||||||
|
- Legacy ARCHIVED status maintained for backward compatibility
|
||||||
|
- ARCHIVED_AND_TRASHED: Files archived to Parquet and kept in TRASH folder (default)
|
||||||
|
- ARCHIVED_AND_PURGED: Files archived to Parquet and deleted from TRASH folder
|
||||||
4. **External Table**: Created automatically based on template table
|
4. **External Table**: Created automatically based on template table
|
||||||
5. **Data Loading**: Data is loaded into target ODS schema
|
5. **Data Loading**: Data is loaded into target ODS schema
|
||||||
6. **Archival**: File is moved to archive bucket after processing
|
6. **Archival**: File is moved to archive bucket after processing
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ This document provides comprehensive documentation for the `FILE_MANAGER.PROCESS
|
|||||||
- **Error Resilient**: Comprehensive error handling and logging for validation and file operations
|
- **Error Resilient**: Comprehensive error handling and logging for validation and file operations
|
||||||
- **Status Tracking**: Updates file processing status throughout validation and preparation workflow
|
- **Status Tracking**: Updates file processing status throughout validation and preparation workflow
|
||||||
|
|
||||||
|
**Migration Context:**
|
||||||
|
- This procedure is part of the **modern Airflow + DBT system** architecture
|
||||||
|
- Creates records in `CT_MRDS.A_SOURCE_FILE_RECEIVED` (modern control table)
|
||||||
|
- For legacy Informatica + WLA data migration, see [System Migration Guide](System_Migration_Informatica_to_Airflow_DBT.md)
|
||||||
|
|
||||||
## Procedure Signatures
|
## Procedure Signatures
|
||||||
|
|
||||||
The procedure is available in two variants:
|
The procedure is available in two variants:
|
||||||
@@ -159,7 +164,9 @@ ORDER BY RECEPTION_DATE DESC;
|
|||||||
| `VALIDATED` | File validation completed successfully | After successful validation |
|
| `VALIDATED` | File validation completed successfully | After successful validation |
|
||||||
| `READY_FOR_INGESTION` | File validated and prepared for Airflow+DBT processing | After successful validation and preparation |
|
| `READY_FOR_INGESTION` | File validated and prepared for Airflow+DBT processing | After successful validation and preparation |
|
||||||
| `INGESTED` | Data has been consumed/ingested by target system | After data consumption |
|
| `INGESTED` | Data has been consumed/ingested by target system | After data consumption |
|
||||||
| `ARCHIVED` | Data exported to PARQUET format and file moved to archival storage | Final archival state using FILE_ARCHIVER |
|
| `ARCHIVED` | (Legacy) Data exported to PARQUET format and file moved to archival storage | Legacy archival state (backward compatibility) |
|
||||||
|
| `ARCHIVED_AND_TRASHED` | Data archived to Parquet, CSV files kept in TRASH folder (default) | Archival with file retention using FILE_ARCHIVER |
|
||||||
|
| `ARCHIVED_AND_PURGED` | Data archived to Parquet, CSV files deleted from TRASH folder | Archival with TRASH cleanup (pKeepInTrash=FALSE) |
|
||||||
| `VALIDATION_FAILED` | File validation failed | After failed validation |
|
| `VALIDATION_FAILED` | File validation failed | After failed validation |
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,122 @@ This guide provides step-by-step instructions for developers on how to properly
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## MANDATORY STANDARDS (NEVER SKIP!)
|
||||||
|
|
||||||
|
### 🔴 Critical: Author Field
|
||||||
|
|
||||||
|
**ALL scripts MUST have:**
|
||||||
|
```sql
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
```
|
||||||
|
|
||||||
|
**❌ WRONG:**
|
||||||
|
```sql
|
||||||
|
-- Author: System
|
||||||
|
-- Author: Developer
|
||||||
|
-- Author: [your name here]
|
||||||
|
```
|
||||||
|
|
||||||
|
**✅ CORRECT:**
|
||||||
|
```sql
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
```
|
||||||
|
|
||||||
|
### 📅 Date Format Standard
|
||||||
|
|
||||||
|
**ISO 8601 format only:**
|
||||||
|
```sql
|
||||||
|
-- Date: 2026-02-03 (YYYY-MM-DD)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 📝 Script Header Template
|
||||||
|
|
||||||
|
**Copy-paste this template for ALL scripts:**
|
||||||
|
```sql
|
||||||
|
-- =====================================================================
|
||||||
|
-- Script: XX_MARS_XXX_description.sql
|
||||||
|
-- MARS Issue: MARS-XXX
|
||||||
|
-- Purpose: Brief description of what this script does
|
||||||
|
-- Author: Grzegorz Michalski
|
||||||
|
-- Date: YYYY-MM-DD
|
||||||
|
-- =====================================================================
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🔐 Database User Requirements
|
||||||
|
|
||||||
|
**Execute installations as ADMIN:**
|
||||||
|
```powershell
|
||||||
|
# ✅ CORRECT
|
||||||
|
Get-Content "install_marsXXX.sql" | sql "ADMIN/password@service"
|
||||||
|
|
||||||
|
# ❌ WRONG
|
||||||
|
Get-Content "install_marsXXX.sql" | sql "CT_MRDS/password@service"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🔍 Data Dictionary Views
|
||||||
|
|
||||||
|
**Use ALL_* views when installing as ADMIN:**
|
||||||
|
```sql
|
||||||
|
-- ✅ CORRECT (ADMIN user)
|
||||||
|
SELECT * FROM ALL_ERRORS WHERE OWNER = 'CT_MRDS' AND NAME = 'PACKAGE_NAME';
|
||||||
|
|
||||||
|
-- ❌ WRONG (shows ADMIN schema, not CT_MRDS)
|
||||||
|
SELECT * FROM USER_ERRORS WHERE NAME = 'PACKAGE_NAME';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 📂 Log Directory Management
|
||||||
|
|
||||||
|
**MANDATORY in all master scripts:**
|
||||||
|
```sql
|
||||||
|
-- Create log/ directory before SPOOL (prevents failures)
|
||||||
|
host mkdir log 2>nul
|
||||||
|
|
||||||
|
-- Then configure dynamic SPOOL filename
|
||||||
|
var filename VARCHAR2(100)
|
||||||
|
BEGIN
|
||||||
|
:filename := 'log/INSTALL_MARS_XXX_' || SYS_CONTEXT('USERENV', 'CON_NAME') || '_' || TO_CHAR(SYSDATE,'YYYYMMDD_HH24MISS') || '.log';
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✋ User Confirmation
|
||||||
|
|
||||||
|
**MANDATORY ACCEPT validation in master scripts:**
|
||||||
|
```sql
|
||||||
|
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(-20001, 'Installation aborted by user');
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
WHENEVER SQLERROR CONTINUE
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🚪 Clean Exit
|
||||||
|
|
||||||
|
**End all master scripts with:**
|
||||||
|
```sql
|
||||||
|
spool off
|
||||||
|
quit; -- ← MANDATORY for clean SQLcl/SQL*Plus exit
|
||||||
|
```
|
||||||
|
|
||||||
|
### 📋 Quick Compliance Checklist
|
||||||
|
|
||||||
|
Before committing any script, verify:
|
||||||
|
- [ ] `Author: Grzegorz Michalski` in header
|
||||||
|
- [ ] Date in ISO 8601 format (YYYY-MM-DD)
|
||||||
|
- [ ] Master scripts use `host mkdir log 2>nul`
|
||||||
|
- [ ] Master scripts require ACCEPT validation
|
||||||
|
- [ ] Master scripts end with `quit;`
|
||||||
|
- [ ] Verification queries use ALL_* views with OWNER filter
|
||||||
|
- [ ] Installation instructions specify ADMIN user
|
||||||
|
|
||||||
|
**💡 Remember:** These standards prevent common mistakes and ensure consistency across all MARS packages!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
1. [Before You Start](#before-you-start)
|
1. [Before You Start](#before-you-start)
|
||||||
@@ -1225,7 +1341,12 @@ SET PAUSE OFF
|
|||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT MARS-XXXX: Rollback Package
|
PROMPT MARS-XXXX: Rollback Package
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
PROMPT WARNING: This will reverse all changes from MARS-XXXX installation!
|
PROMPT This will reverse all changes from MARS-XXXX installation
|
||||||
|
PROMPT
|
||||||
|
PROMPT Rollback steps:
|
||||||
|
PROMPT 1. Restore previous package version
|
||||||
|
PROMPT 2. Remove added columns/tables
|
||||||
|
PROMPT 3. Revert configuration changes
|
||||||
PROMPT =========================================================================
|
PROMPT =========================================================================
|
||||||
|
|
||||||
-- Confirm rollback with user
|
-- Confirm rollback with user
|
||||||
@@ -1259,6 +1380,32 @@ spool off
|
|||||||
- Revert configuration changes
|
- Revert configuration changes
|
||||||
- Include verification step after rollback (@@verify_packages_version.sql)
|
- Include verification step after rollback (@@verify_packages_version.sql)
|
||||||
|
|
||||||
|
**Rollback Communication Style:**
|
||||||
|
- ✅ **DO**: Use calm, professional tone describing what will be done
|
||||||
|
- ✅ **DO**: List specific rollback steps clearly
|
||||||
|
- ❌ **DON'T**: Use dramatic words like "WARNING", "CRITICAL IMPACT", "DANGER"
|
||||||
|
- ❌ **DON'T**: Create panic - rollback is a normal part of deployment process
|
||||||
|
- **Rationale**: Rollbacks happen when installations fail or need to be reversed. This is a standard procedure, not an emergency.
|
||||||
|
|
||||||
|
**Example - Professional vs. Dramatic:**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- ✅ CORRECT - Professional and Clear
|
||||||
|
PROMPT This will reverse all changes from MARS-828 installation
|
||||||
|
PROMPT
|
||||||
|
PROMPT Rollback steps:
|
||||||
|
PROMPT 1. Remove validation trigger
|
||||||
|
PROMPT 2. Drop ARCHIVAL_STRATEGY and MINIMUM_AGE_MONTHS columns
|
||||||
|
PROMPT 3. Restore FILE_ARCHIVER package to v2.0.0
|
||||||
|
|
||||||
|
-- ❌ WRONG - Unnecessarily Dramatic
|
||||||
|
PROMPT WARNING: This will restore FILE_ARCHIVER to v2.0.0
|
||||||
|
PROMPT
|
||||||
|
PROMPT CRITICAL IMPACT:
|
||||||
|
PROMPT 1. All archival strategies revert to THRESHOLD_BASED
|
||||||
|
PROMPT 2. ARCHIVAL_STRATEGY and MINIMUM_AGE_MONTHS columns will be dropped
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Version Tracking Integration
|
### Version Tracking Integration
|
||||||
|
|||||||
448
confluence/System_Migration_Informatica_to_Airflow_DBT.md
Normal file
448
confluence/System_Migration_Informatica_to_Airflow_DBT.md
Normal file
@@ -0,0 +1,448 @@
|
|||||||
|
# System Migration: Informatica + WLA → Airflow + DBT
|
||||||
|
|
||||||
|
This document describes the migration from the legacy Informatica + WLA data processing system to the modern Airflow + DBT architecture, including control table differences, data export strategies, and known limitations.
|
||||||
|
|
||||||
|
## Migration Overview
|
||||||
|
|
||||||
|
The MRDS (Market Reference Data System) is undergoing a fundamental technology migration:
|
||||||
|
|
||||||
|
**Legacy System (Informatica + WLA):**
|
||||||
|
- ETL Tool: Informatica PowerCenter
|
||||||
|
- Workflow Orchestration: WLA (Workflow Automation)
|
||||||
|
- Control Schema: `CT_ODS` (Operational Data Store Control)
|
||||||
|
- Primary Control Table: `CT_ODS.A_LOAD_HISTORY`
|
||||||
|
- Key Column: `A_ETL_LOAD_SET_KEY`
|
||||||
|
|
||||||
|
**Modern System (Airflow + DBT):**
|
||||||
|
- Orchestration: Apache Airflow
|
||||||
|
- Transformation: DBT (Data Build Tool)
|
||||||
|
- Control Schema: `CT_MRDS` (MRDS Control)
|
||||||
|
- Primary Control Tables: `CT_MRDS.A_SOURCE_FILE_RECEIVED`, `CT_MRDS.A_WORKFLOW_HISTORY`
|
||||||
|
- Key Column: `A_WORKFLOW_HISTORY_KEY`
|
||||||
|
|
||||||
|
## Control Table Architecture
|
||||||
|
|
||||||
|
### Legacy System: CT_ODS.A_LOAD_HISTORY
|
||||||
|
|
||||||
|
**Purpose**: Tracks Informatica PowerCenter workflow executions
|
||||||
|
|
||||||
|
**Structure**:
|
||||||
|
```sql
|
||||||
|
DESC CT_ODS.A_LOAD_HISTORY;
|
||||||
|
|
||||||
|
Name Type
|
||||||
|
______________________ _____________________
|
||||||
|
A_ETL_LOAD_SET_KEY NUMBER(38) -- Primary key
|
||||||
|
WORKFLOW_NAME VARCHAR2(255) -- Informatica workflow name
|
||||||
|
INFA_RUN_ID NUMBER(38) -- Informatica run ID
|
||||||
|
LOAD_START TIMESTAMP(6) -- Workflow start time
|
||||||
|
LOAD_END TIMESTAMP(6) -- Workflow end time
|
||||||
|
EXDI_APPL_REQ_ID VARCHAR2(255)
|
||||||
|
EXDI_CORRELATION_ID VARCHAR2(255)
|
||||||
|
LOAD_SUCCESSFUL CHAR(1) -- Y/N success flag
|
||||||
|
WLA_RUN_ID NUMBER(28) -- WLA run ID
|
||||||
|
DQ_FLAG VARCHAR2(5) -- Data quality flag
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage Pattern**:
|
||||||
|
- Created by Informatica workflows during ETL execution
|
||||||
|
- Used for temporal partitioning in DATA_EXPORTER
|
||||||
|
- Referenced via `A_ETL_LOAD_SET_KEY_FK` foreign key in data tables
|
||||||
|
|
||||||
|
### Modern System: CT_MRDS Control Tables
|
||||||
|
|
||||||
|
#### 1. A_SOURCE_FILE_RECEIVED
|
||||||
|
|
||||||
|
**Purpose**: Tracks individual file processing through the complete lifecycle
|
||||||
|
|
||||||
|
**Key Columns**:
|
||||||
|
```sql
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY NUMBER -- Primary key
|
||||||
|
SOURCE_FILE_NAME VARCHAR2 -- Full OCI path
|
||||||
|
PROCESSING_STATUS VARCHAR2 -- Status tracking
|
||||||
|
RECEPTION_DATE DATE -- File arrival timestamp
|
||||||
|
PARTITION_YEAR VARCHAR2(4) -- Archive partition (year)
|
||||||
|
PARTITION_MONTH VARCHAR2(2) -- Archive partition (month)
|
||||||
|
ARCH_FILE_NAME VARCHAR2 -- Parquet archive file path
|
||||||
|
```
|
||||||
|
|
||||||
|
**Status Workflow**:
|
||||||
|
```
|
||||||
|
RECEIVED → VALIDATED → READY_FOR_INGESTION → INGESTED → ARCHIVED_AND_TRASHED → ARCHIVED_AND_PURGED (optional)
|
||||||
|
|
||||||
|
Note: Legacy ARCHIVED status maintained for backward compatibility
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage Pattern**:
|
||||||
|
- Created by FILE_MANAGER.PROCESS_SOURCE_FILE during file validation
|
||||||
|
- Updated throughout file lifecycle (validation, ingestion, archival)
|
||||||
|
- Required by FILE_ARCHIVER for archival operations
|
||||||
|
- Links to A_WORKFLOW_HISTORY via workflow execution
|
||||||
|
|
||||||
|
#### 2. A_WORKFLOW_HISTORY
|
||||||
|
|
||||||
|
**Purpose**: Tracks Airflow + DBT workflow executions (similar role to A_LOAD_HISTORY)
|
||||||
|
|
||||||
|
**Key Columns**:
|
||||||
|
```sql
|
||||||
|
A_WORKFLOW_HISTORY_KEY NUMBER -- Primary key
|
||||||
|
WORKFLOW_NAME VARCHAR2 -- Airflow DAG name
|
||||||
|
WORKFLOW_START TIMESTAMP -- Workflow start time
|
||||||
|
WORKFLOW_END TIMESTAMP -- Workflow end time
|
||||||
|
WORKFLOW_SUCCESSFUL CHAR(1) -- Y/N success flag
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage Pattern**:
|
||||||
|
- Created by Airflow + DBT workflows during data processing
|
||||||
|
- Used for temporal partitioning decisions in FILE_ARCHIVER
|
||||||
|
- Referenced via `A_WORKFLOW_HISTORY_KEY_FK` foreign key in data tables
|
||||||
|
|
||||||
|
## Data Export Strategies
|
||||||
|
|
||||||
|
### Scenario 1: Legacy Data Export (Informatica → ODS)
|
||||||
|
|
||||||
|
**Use Case**: One-time migration of historical data loaded by Informatica
|
||||||
|
|
||||||
|
**Package**: `DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE`
|
||||||
|
|
||||||
|
**Control Table**: Uses `CT_ODS.A_LOAD_HISTORY` for temporal partitioning
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
```sql
|
||||||
|
-- Export historical AGGREGATED_ALLOTMENT data (loaded by Informatica)
|
||||||
|
BEGIN
|
||||||
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
||||||
|
pSchemaName => 'OU_TOP',
|
||||||
|
pTableName => 'AGGREGATED_ALLOTMENT',
|
||||||
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK', -- Links to A_LOAD_HISTORY
|
||||||
|
pBucketArea => 'DATA',
|
||||||
|
pFolderName => 'legacy_migration',
|
||||||
|
pMinDate => DATE '2020-01-01',
|
||||||
|
pMaxDate => DATE '2024-12-31'
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Result**: CSV files in ODS bucket (DATA area), partitioned by LOAD_START from A_LOAD_HISTORY
|
||||||
|
|
||||||
|
### Scenario 2: Modern System Data (Airflow + DBT → ODS → ARCHIVE)
|
||||||
|
|
||||||
|
**Use Case**: Ongoing processing with new Airflow + DBT system
|
||||||
|
|
||||||
|
**Workflow**:
|
||||||
|
1. **File Arrival**: FILES → INBOX bucket
|
||||||
|
2. **Validation**: FILE_MANAGER.PROCESS_SOURCE_FILE → creates A_SOURCE_FILE_RECEIVED
|
||||||
|
3. **Processing**: Airflow + DBT → creates A_WORKFLOW_HISTORY
|
||||||
|
4. **Export**: DATA_EXPORTER → moves to ODS bucket (DATA area)
|
||||||
|
5. **Archival**: FILE_ARCHIVER → moves to ARCHIVE bucket (Parquet with Hive partitioning)
|
||||||
|
|
||||||
|
**Control Tables**: Uses both A_SOURCE_FILE_RECEIVED and A_WORKFLOW_HISTORY
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
```sql
|
||||||
|
-- Archival of data processed by Airflow + DBT
|
||||||
|
BEGIN
|
||||||
|
CT_MRDS.FILE_ARCHIVER.ARCHIVE_TABLE_DATA(
|
||||||
|
pSourceFileConfig => vConfig -- Requires A_SOURCE_FILE_RECEIVED records
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Critical Gap: Legacy Data Archival
|
||||||
|
|
||||||
|
### Problem Statement
|
||||||
|
|
||||||
|
**Scenario**: Historical data exported using DATA_EXPORTER from Informatica-loaded tables
|
||||||
|
|
||||||
|
**Issue**: FILE_ARCHIVER requires records in `A_SOURCE_FILE_RECEIVED`, but legacy exports don't create them
|
||||||
|
|
||||||
|
**Impact**: Legacy data exported to ODS/DATA bucket **CANNOT** be archived to ARCHIVE bucket using FILE_ARCHIVER
|
||||||
|
|
||||||
|
### Technical Analysis
|
||||||
|
|
||||||
|
**DATA_EXPORTER Behavior**:
|
||||||
|
```sql
|
||||||
|
-- Uses A_LOAD_HISTORY for partitioning (Informatica workflows)
|
||||||
|
SELECT DISTINCT TO_CHAR(L.LOAD_START,'YYYY') AS YR,
|
||||||
|
TO_CHAR(L.LOAD_START,'MM') AS MN
|
||||||
|
FROM OU_TOP.AGGREGATED_ALLOTMENT T, CT_ODS.A_LOAD_HISTORY L
|
||||||
|
WHERE T.A_ETL_LOAD_SET_KEY_FK = L.A_ETL_LOAD_SET_KEY
|
||||||
|
AND L.LOAD_START >= :pMinDate
|
||||||
|
AND L.LOAD_START < :pMaxDate;
|
||||||
|
|
||||||
|
-- Creates CSV files: ODS/legacy_migration/AGGREGATED_ALLOTMENT_YYYYMM.csv
|
||||||
|
-- Does NOT create A_SOURCE_FILE_RECEIVED records
|
||||||
|
```
|
||||||
|
|
||||||
|
**FILE_ARCHIVER Requirement**:
|
||||||
|
```sql
|
||||||
|
-- Joins A_SOURCE_FILE_RECEIVED with A_WORKFLOW_HISTORY
|
||||||
|
JOIN CT_MRDS.A_SOURCE_FILE_RECEIVED r
|
||||||
|
ON r.A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfig.A_SOURCE_FILE_CONFIG_KEY
|
||||||
|
AND r.PROCESSING_STATUS = 'INGESTED';
|
||||||
|
|
||||||
|
-- Without A_SOURCE_FILE_RECEIVED records, archival CANNOT proceed
|
||||||
|
```
|
||||||
|
|
||||||
|
### Workaround Strategies
|
||||||
|
|
||||||
|
#### Strategy 1: Manual Registration (Recommended for Small Datasets)
|
||||||
|
|
||||||
|
Manually create `A_SOURCE_FILE_RECEIVED` records for legacy exported files:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Step 1: Export legacy data to ODS/DATA
|
||||||
|
BEGIN
|
||||||
|
DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
||||||
|
pSchemaName => 'OU_TOP',
|
||||||
|
pTableName => 'AGGREGATED_ALLOTMENT',
|
||||||
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
|
pBucketArea => 'DATA',
|
||||||
|
pFolderName => 'legacy_export',
|
||||||
|
pMinDate => DATE '2024-01-01',
|
||||||
|
pMaxDate => DATE '2024-12-31'
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
-- Step 2: List exported CSV files
|
||||||
|
SELECT object_name, time_created, bytes
|
||||||
|
FROM TABLE(MRDS_LOADER.cloud_wrapper.list_objects(
|
||||||
|
credential_name => 'DEF_CRED_ARN',
|
||||||
|
location_uri => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/frtgjxu7zl7c/b/data/o/'
|
||||||
|
)) WHERE object_name LIKE 'ODS/legacy_export/AGGREGATED_ALLOTMENT_%';
|
||||||
|
|
||||||
|
-- Step 3: Manually register each file in A_SOURCE_FILE_RECEIVED
|
||||||
|
-- (Requires source configuration for AGGREGATED_ALLOTMENT to exist)
|
||||||
|
INSERT INTO CT_MRDS.A_SOURCE_FILE_RECEIVED (
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY,
|
||||||
|
A_SOURCE_FILE_CONFIG_KEY,
|
||||||
|
SOURCE_FILE_NAME,
|
||||||
|
PROCESSING_STATUS,
|
||||||
|
RECEPTION_DATE,
|
||||||
|
BYTES,
|
||||||
|
CHECKSUM,
|
||||||
|
EXTERNAL_TABLE_NAME
|
||||||
|
) VALUES (
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY_SEQ.NEXTVAL,
|
||||||
|
(SELECT A_SOURCE_FILE_CONFIG_KEY FROM A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_ID = 'AGGREGATED_ALLOTMENT' AND SOURCE_FILE_TYPE = 'INPUT'),
|
||||||
|
'ODS/legacy_export/AGGREGATED_ALLOTMENT_202401.csv',
|
||||||
|
'INGESTED', -- Skip validation, mark as already ingested
|
||||||
|
DATE '2024-01-15',
|
||||||
|
1048576, -- File size in bytes
|
||||||
|
'manual_registration',
|
||||||
|
NULL -- No external table needed
|
||||||
|
);
|
||||||
|
-- Repeat for all exported CSV files
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
-- Step 4: Now FILE_ARCHIVER can process these files
|
||||||
|
BEGIN
|
||||||
|
FILE_ARCHIVER.ARCHIVE_TABLE_DATA(pSourceFileConfig => vConfig);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Strategy 2: Direct Archive Export (Bypass ODS)
|
||||||
|
|
||||||
|
Skip ODS/DATA bucket entirely - export directly to ARCHIVE bucket in Parquet format:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Export legacy data directly to ARCHIVE bucket
|
||||||
|
BEGIN
|
||||||
|
DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
||||||
|
pSchemaName => 'OU_TOP',
|
||||||
|
pTableName => 'AGGREGATED_ALLOTMENT',
|
||||||
|
pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK',
|
||||||
|
pBucketArea => 'ARCHIVE', -- Direct to archive
|
||||||
|
pFolderName => 'legacy_direct',
|
||||||
|
pMinDate => DATE '2020-01-01',
|
||||||
|
pMaxDate => DATE '2024-12-31'
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
-- Result: Parquet files with Hive partitioning in ARCHIVE bucket
|
||||||
|
-- Files: ARCHIVE/legacy_direct/PARTITION_YEAR=2024/PARTITION_MONTH=01/*.parquet
|
||||||
|
-- No A_SOURCE_FILE_RECEIVED records needed (archival already complete)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pros**:
|
||||||
|
- Simple, no manual registration
|
||||||
|
- Data already in final archive format (Parquet)
|
||||||
|
- Hive-style partitioning automatically applied
|
||||||
|
|
||||||
|
**Cons**:
|
||||||
|
- No record in A_SOURCE_FILE_RECEIVED (tracking gap)
|
||||||
|
- Cannot use FILE_ARCHIVER features (archival strategies, status tracking)
|
||||||
|
- Mixed folder structure (legacy_direct vs. standard source/table paths)
|
||||||
|
|
||||||
|
#### Strategy 3: Hybrid Approach (Recommended for Large Datasets)
|
||||||
|
|
||||||
|
Use DATA_EXPORTER for initial export, create minimal A_SOURCE_FILE_RECEIVED records programmatically:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Create helper procedure to register legacy exports
|
||||||
|
CREATE OR REPLACE PROCEDURE REGISTER_LEGACY_EXPORT (
|
||||||
|
pSourceFileId VARCHAR2,
|
||||||
|
pBucketArea VARCHAR2,
|
||||||
|
pFolderName VARCHAR2,
|
||||||
|
pFilePattern VARCHAR2,
|
||||||
|
pReceptionDate DATE DEFAULT SYSDATE
|
||||||
|
) AS
|
||||||
|
vConfigKey NUMBER;
|
||||||
|
vBucketUri VARCHAR2(500);
|
||||||
|
vPrefix VARCHAR2(500);
|
||||||
|
BEGIN
|
||||||
|
-- Get source configuration
|
||||||
|
SELECT A_SOURCE_FILE_CONFIG_KEY
|
||||||
|
INTO vConfigKey
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_ID = pSourceFileId
|
||||||
|
AND SOURCE_FILE_TYPE = 'INPUT';
|
||||||
|
|
||||||
|
-- Get bucket URI
|
||||||
|
vBucketUri := CT_MRDS.ENV_MANAGER.GET_BUCKET_URI(pBucketArea);
|
||||||
|
vPrefix := 'ODS/' || pFolderName || '/';
|
||||||
|
|
||||||
|
-- Register all matching files
|
||||||
|
FOR rec IN (
|
||||||
|
SELECT object_name, bytes, etag
|
||||||
|
FROM TABLE(MRDS_LOADER.cloud_wrapper.list_objects(
|
||||||
|
credential_name => 'DEF_CRED_ARN',
|
||||||
|
location_uri => vBucketUri
|
||||||
|
))
|
||||||
|
WHERE object_name LIKE vPrefix || pFilePattern
|
||||||
|
) LOOP
|
||||||
|
INSERT INTO CT_MRDS.A_SOURCE_FILE_RECEIVED (
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY,
|
||||||
|
A_SOURCE_FILE_CONFIG_KEY,
|
||||||
|
SOURCE_FILE_NAME,
|
||||||
|
PROCESSING_STATUS,
|
||||||
|
RECEPTION_DATE,
|
||||||
|
BYTES,
|
||||||
|
CHECKSUM
|
||||||
|
) VALUES (
|
||||||
|
A_SOURCE_FILE_RECEIVED_KEY_SEQ.NEXTVAL,
|
||||||
|
vConfigKey,
|
||||||
|
rec.object_name,
|
||||||
|
'INGESTED',
|
||||||
|
pReceptionDate,
|
||||||
|
rec.bytes,
|
||||||
|
rec.etag
|
||||||
|
);
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
DBMS_OUTPUT.PUT_LINE('Registered ' || SQL%ROWCOUNT || ' legacy files');
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
-- Usage:
|
||||||
|
BEGIN
|
||||||
|
-- After DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE completes
|
||||||
|
REGISTER_LEGACY_EXPORT(
|
||||||
|
pSourceFileId => 'AGGREGATED_ALLOTMENT',
|
||||||
|
pBucketArea => 'DATA',
|
||||||
|
pFolderName => 'legacy_export',
|
||||||
|
pFilePattern => 'AGGREGATED_ALLOTMENT_2024%.csv',
|
||||||
|
pReceptionDate => DATE '2024-12-31'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Now FILE_ARCHIVER can process
|
||||||
|
FILE_ARCHIVER.ARCHIVE_TABLE_DATA(pSourceFileConfig => vConfig);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Timeline and Coexistence
|
||||||
|
|
||||||
|
### Phase 1: Legacy System Only (Before Migration)
|
||||||
|
- All data loaded via Informatica + WLA
|
||||||
|
- Control table: `CT_ODS.A_LOAD_HISTORY`
|
||||||
|
- No `A_SOURCE_FILE_RECEIVED` records
|
||||||
|
|
||||||
|
### Phase 2: Parallel Operation (During Migration)
|
||||||
|
- **Old data**: Continue using Informatica + WLA → A_LOAD_HISTORY
|
||||||
|
- **New data**: Start using Airflow + DBT → A_SOURCE_FILE_RECEIVED + A_WORKFLOW_HISTORY
|
||||||
|
- **Challenge**: Different control tables for different data vintages
|
||||||
|
|
||||||
|
### Phase 3: New System Only (After Migration)
|
||||||
|
- All new data via Airflow + DBT
|
||||||
|
- Legacy data archived (one-time export using DATA_EXPORTER)
|
||||||
|
- Control tables: `CT_MRDS.A_SOURCE_FILE_RECEIVED`, `CT_MRDS.A_WORKFLOW_HISTORY`
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
|
||||||
|
### For New Data (Airflow + DBT)
|
||||||
|
✅ Use standard workflow:
|
||||||
|
1. FILE_MANAGER.PROCESS_SOURCE_FILE (creates A_SOURCE_FILE_RECEIVED)
|
||||||
|
2. Airflow + DBT processing (creates A_WORKFLOW_HISTORY)
|
||||||
|
3. FILE_ARCHIVER.ARCHIVE_TABLE_DATA (uses both control tables)
|
||||||
|
|
||||||
|
### For Legacy Data Migration
|
||||||
|
✅ **Small Datasets (<1000 files)**: Strategy 1 (Manual Registration)
|
||||||
|
✅ **Large Datasets (>1000 files)**: Strategy 2 (Direct to ARCHIVE) or Strategy 3 (Hybrid)
|
||||||
|
❌ **Avoid**: Exporting to ODS/DATA without registration (orphaned files, cannot archive)
|
||||||
|
|
||||||
|
### Configuration Requirements
|
||||||
|
|
||||||
|
Before archiving legacy data, ensure source configuration exists:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Check if configuration exists
|
||||||
|
SELECT A_SOURCE_FILE_CONFIG_KEY, SOURCE_FILE_ID, TABLE_ID, ARCHIVAL_STRATEGY
|
||||||
|
FROM CT_MRDS.A_SOURCE_FILE_CONFIG
|
||||||
|
WHERE SOURCE_FILE_ID = 'YOUR_SOURCE_FILE_ID';
|
||||||
|
|
||||||
|
-- If missing, create configuration
|
||||||
|
CALL FILE_MANAGER.ADD_SOURCE_FILE_CONFIG(
|
||||||
|
pSourceKey => 'YOUR_SOURCE',
|
||||||
|
pSourceFileType => 'INPUT',
|
||||||
|
pSourceFileId => 'YOUR_SOURCE_FILE_ID',
|
||||||
|
pSourceFileDesc => 'Legacy migrated data',
|
||||||
|
pSourceFileNamePattern => 'pattern_*.csv',
|
||||||
|
pTableId => 'YOUR_TABLE_ID',
|
||||||
|
pTemplateTableName => 'CT_ET_TEMPLATES.YOUR_TEMPLATE'
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Known Limitations
|
||||||
|
|
||||||
|
### 1. No Retroactive A_SOURCE_FILE_RECEIVED Creation
|
||||||
|
DATA_EXPORTER does not automatically create A_SOURCE_FILE_RECEIVED records when exporting legacy data. This is by design - it's a one-time export tool, not a file tracking system.
|
||||||
|
|
||||||
|
### 2. FILE_ARCHIVER Requires A_SOURCE_FILE_RECEIVED
|
||||||
|
FILE_ARCHIVER cannot archive data without corresponding A_SOURCE_FILE_RECEIVED records. This prevents archiving of:
|
||||||
|
- Legacy Informatica-loaded data exported via DATA_EXPORTER
|
||||||
|
- Manually uploaded files not processed through FILE_MANAGER.PROCESS_SOURCE_FILE
|
||||||
|
|
||||||
|
### 3. Mixed Control Table References
|
||||||
|
During migration period, some procedures reference A_LOAD_HISTORY (DATA_EXPORTER) while others reference A_WORKFLOW_HISTORY (FILE_ARCHIVER). This is intentional but requires careful understanding of data lineage.
|
||||||
|
|
||||||
|
### 4. A_WORKFLOW_HISTORY vs A_LOAD_HISTORY Column Mismatch
|
||||||
|
The control tables have different schemas:
|
||||||
|
- **A_LOAD_HISTORY**: `LOAD_START`, `A_ETL_LOAD_SET_KEY`
|
||||||
|
- **A_WORKFLOW_HISTORY**: `WORKFLOW_START`, `A_WORKFLOW_HISTORY_KEY`
|
||||||
|
|
||||||
|
Test scripts must be aware of which table is being used.
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
- [PROCESS_SOURCE_FILE Guide](PROCESS_SOURCE_FILE_Guide.md) - File validation and ingestion workflow
|
||||||
|
- [FILE_ARCHIVER Guide](FILE_ARCHIVER_Guide.md) - Archival strategies and configuration
|
||||||
|
- [FILE_MANAGER Configuration Guide](FILE_MANAGER_Configuration_Guide.md) - System configuration
|
||||||
|
- [Package Deployment Guide](Package_Deployment_Guide.md) - Deployment procedures
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
The migration from Informatica + WLA to Airflow + DBT introduces new control tables (`A_SOURCE_FILE_RECEIVED`, `A_WORKFLOW_HISTORY`) while maintaining compatibility with legacy control tables (`A_LOAD_HISTORY`). Understanding the relationship between these tables is critical for:
|
||||||
|
|
||||||
|
- **Data Lineage**: Tracking which system processed which data
|
||||||
|
- **Export Operations**: Choosing appropriate DATA_EXPORTER procedures
|
||||||
|
- **Archival Operations**: Ensuring FILE_ARCHIVER has required metadata
|
||||||
|
- **Testing**: Using correct control tables in test scenarios
|
||||||
|
|
||||||
|
The recommended approach for legacy data migration is **Strategy 2 (Direct to ARCHIVE)** for large datasets, as it avoids the complexity of manual A_SOURCE_FILE_RECEIVED registration while achieving the goal of moving historical data to long-term archival storage.
|
||||||
@@ -394,6 +394,9 @@ DATA Bucket:
|
|||||||
├── ODS/
|
├── ODS/
|
||||||
│ └── {SOURCE}/
|
│ └── {SOURCE}/
|
||||||
│ └── {TABLE_NAME}/
|
│ └── {TABLE_NAME}/
|
||||||
|
└── TRASH/ -- File retention subfolder (not a separate bucket)
|
||||||
|
└── {SOURCE}/
|
||||||
|
└── {TABLE_NAME}/ -- CSV files after archival (ARCHIVED_AND_TRASHED status)
|
||||||
|
|
||||||
ARCHIVE Bucket:
|
ARCHIVE Bucket:
|
||||||
└── ARCHIVE/
|
└── ARCHIVE/
|
||||||
@@ -402,6 +405,8 @@ ARCHIVE Bucket:
|
|||||||
└── PARTITION_YEAR=*/
|
└── PARTITION_YEAR=*/
|
||||||
└── PARTITION_MONTH=*/
|
└── PARTITION_MONTH=*/
|
||||||
└── *.parquet
|
└── *.parquet
|
||||||
|
|
||||||
|
Note: TRASH is a subfolder within the DATA bucket for file retention and rollback capability.
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Migration Checklist
|
### 4. Migration Checklist
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ WHEN OTHERS THEN
|
|||||||
```sql
|
```sql
|
||||||
-- Dodano 'VALIDATION_FAILED' do dozwolonych statusów
|
-- Dodano 'VALIDATION_FAILED' do dozwolonych statusów
|
||||||
PROCESSING_STATUS IN ('RECEIVED', 'VALIDATED', 'READY_FOR_INGESTION',
|
PROCESSING_STATUS IN ('RECEIVED', 'VALIDATED', 'READY_FOR_INGESTION',
|
||||||
'INGESTED', 'ARCHIVED', 'VALIDATION_FAILED')
|
'INGESTED', 'ARCHIVED', 'ARCHIVED_AND_TRASHED',
|
||||||
|
'ARCHIVED_AND_PURGED', 'VALIDATION_FAILED')
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📊 Testowanie
|
## 📊 Testowanie
|
||||||
|
|||||||
Reference in New Issue
Block a user