From cad6e63479e2cb7854e244d9eae601a64e1fa89f Mon Sep 17 00:00:00 2001 From: Grzegorz Michalski Date: Mon, 2 Mar 2026 13:51:59 +0100 Subject: [PATCH] exported files from dev --- .../CT_MRDS/export/A_CASPER_FILEVAULT.sql | 18 + .../CT_MRDS/export/A_COLUMN_DATE_FORMAT.sql | 19 + .../A_COLUMN_DATE_FORMAT_CONSTRAINT.sql | 13 + .../export/A_COLUMN_DATE_FORMAT_PK.sql | 10 + .../export/A_COLUMN_DATE_FORMAT_PK_1.sql | 10 + .../export/A_DEVO_METADATA_INVENTORY.sql | 26 + .../A_DEVO_METADATA_INVENTORY_CONSTRAINT.sql | 8 + .../export/A_DEVO_REPLICA_MGMT_LOG.sql | 26 + .../A_DEVO_REPLICA_MGMT_LOG_CONSTRAINT.sql | 10 + .../export/A_DEVO_REPLICA_MGMT_MOPDB.sql | 23 + .../A_DEVO_REPLICA_MGMT_MOPDB_CONSTRAINT.sql | 10 + .../export/A_DEVO_REPLICA_MGMT_RAR.sql | 23 + .../A_DEVO_REPLICA_MGMT_RAR_CONSTRAINT.sql | 10 + .../export/A_DEVO_REPLICA_MGMT_RAR_TRG.sql | 55 + .../export/A_DEVO_REPLICA_MGMT_RAR_TRG_1.sql | 55 + .../export/A_DEVO_REPLICA_MGMT_RQSD.sql | 23 + .../A_DEVO_REPLICA_MGMT_RQSD_CONSTRAINT.sql | 10 + .../CT_MRDS/export/A_DEVO_SOURCES_IGAM.sql | 17 + .../CT_MRDS/export/A_FILE_MANAGER_CONFIG.sql | 16 + .../A_FILE_MANAGER_CONFIG_CONSTRAINT.sql | 10 + .../CT_MRDS/export/A_MOPDB_LOAD_HISTORY.sql | 24 + .../export/A_PACKAGE_VERSION_TRACKING.sql | 35 + .../A_PACKAGE_VERSION_TRACKING_CONSTRAINT.sql | 24 + .../export/A_PARALLEL_EXPORT_CHUNKS.sql | 58 + .../A_PARALLEL_EXPORT_CHUNKS_CONSTRAINT.sql | 26 + .../database/CT_MRDS/export/A_PROCESS_LOG.sql | 24 + .../export/A_PROCESS_LOG_CONSTRAINT.sql | 11 + .../database/CT_MRDS/export/A_SOURCE.sql | 18 + .../CT_MRDS/export/A_SOURCE_CONSTRAINT.sql | 10 + .../CT_MRDS/export/A_SOURCE_FILE_CONFIG.sql | 61 + .../A_SOURCE_FILE_CONFIG_CONSTRAINT.sql | 31 + .../export/A_SOURCE_FILE_CONFIG_KEY_SEQ.sql | 6 + .../export/A_SOURCE_FILE_CONFIG_PK.sql | 10 + .../export/A_SOURCE_FILE_CONFIG_PK_1.sql | 10 + .../A_SOURCE_FILE_CONFIG_REFCONSTRAINT.sql | 8 + .../export/A_SOURCE_FILE_CONFIG_UQ1.sql | 10 + .../export/A_SOURCE_FILE_CONFIG_UQ1_1.sql | 10 + .../CT_MRDS/export/A_SOURCE_FILE_RECEIVED.sql | 43 + .../A_SOURCE_FILE_RECEIVED_CONSTRAINT.sql | 24 + .../export/A_SOURCE_FILE_RECEIVED_KEY_SEQ.sql | 6 + .../export/A_SOURCE_FILE_RECEIVED_PK.sql | 10 + .../export/A_SOURCE_FILE_RECEIVED_PK_1.sql | 10 + .../A_SOURCE_FILE_RECEIVED_REFCONSTRAINT.sql | 6 + .../export/A_SOURCE_FILE_RECEIVED_UK1.sql | 10 + .../export/A_SOURCE_FILE_RECEIVED_UK1_1.sql | 10 + .../database/CT_MRDS/export/A_SOURCE_PK.sql | 10 + .../database/CT_MRDS/export/A_SOURCE_PK_1.sql | 10 + .../database/CT_MRDS/export/A_TABLE_STAT.sql | 23 + .../export/A_TABLE_STAT_CONSTRAINT.sql | 18 + .../CT_MRDS/export/A_TABLE_STAT_HIST.sql | 23 + .../export/A_TABLE_STAT_HIST_CONSTRAINT.sql | 12 + .../CT_MRDS/export/A_TABLE_STAT_KEY_SEQ.sql | 6 + .../CT_MRDS/export/A_TABLE_STAT_UK1.sql | 10 + .../CT_MRDS/export/A_TABLE_STAT_UK1_1.sql | 10 + .../CT_MRDS/export/A_TASK_HISTORY.sql | 30 + .../CT_MRDS/export/A_TASK_HISTORY_KEY_SEQ.sql | 6 + .../CT_MRDS/export/A_TASK_HISTORY_SOURCE.sql | 26 + .../export/A_TASK_HISTORY_SOURCE_KEY_SEQ.sql | 6 + .../CT_MRDS/export/A_TASK_HISTORY_TARGET.sql | 28 + .../export/A_TASK_HISTORY_TARGET_KEY_SEQ.sql | 6 + .../CT_MRDS/export/A_WORKFLOW_HISTORY.sql | 320 +++ .../CT_MRDS/export/A_WORKFLOW_HISTORY_1.sql | 339 +++ .../CT_MRDS/export/A_WORKFLOW_HISTORY_2.sql | 339 +++ .../export/A_WORKFLOW_HISTORY_KEY_SEQ.sql | 6 + .../export/A_WORKFLOW_HISTORY_PROPERTY.sql | 16 + .../A_WORKFLOW_HISTORY_PROPERTY_IDX1.sql | 10 + .../A_WORKFLOW_HISTORY_PROPERTY_IDX1_1.sql | 10 + .../database/CT_MRDS/export/CHECK_LINK.sql | 22 + .../database/CT_MRDS/export/CT_MRDS.7z | Bin 0 -> 68522 bytes .../database/CT_MRDS/export/DATA_EXPORTER.sql | 247 ++ .../CT_MRDS/export/DATA_EXPORTER_1.sql | 1786 ++++++++++++ .../CT_MRDS/export/DBMS_REGISTRY_SYS.sql | 5 + .../database/CT_MRDS/export/DRARIDMC.sql | 7 + .../database/CT_MRDS/export/ENV_MANAGER.sql | 630 +++++ .../database/CT_MRDS/export/ENV_MANAGER_1.sql | 1173 ++++++++ .../database/CT_MRDS/export/ERR_LOG.sql | 25 + .../database/CT_MRDS/export/FILE_ARCHIVER.sql | 283 ++ .../CT_MRDS/export/FILE_ARCHIVER_1.sql | 1288 +++++++++ .../database/CT_MRDS/export/FILE_MANAGER.sql | 730 +++++ .../CT_MRDS/export/FILE_MANAGER_1.sql | 2401 +++++++++++++++++ .../export/Generated-20260302130055.sql | 114 + .../export/M_DWH_ADD_LOAD_INFO_START.sql | 11 + .../export/PK_PARALLEL_EXPORT_CHUNKS.sql | 10 + .../export/PK_PARALLEL_EXPORT_CHUNKS_1.sql | 10 + .../database/CT_MRDS/export/SYS_C00142356.sql | 10 + .../CT_MRDS/export/SYS_C00142356_1.sql | 10 + .../database/CT_MRDS/export/SYS_C0062744.sql | 10 + .../CT_MRDS/export/SYS_C0062744_1.sql | 10 + .../database/CT_MRDS/export/SYS_C0062752.sql | 10 + .../CT_MRDS/export/SYS_C0062752_1.sql | 10 + .../database/CT_MRDS/export/SYS_C0062756.sql | 10 + .../CT_MRDS/export/SYS_C0062756_1.sql | 10 + .../database/CT_MRDS/export/SYS_C0062776.sql | 10 + .../CT_MRDS/export/SYS_C0062776_1.sql | 10 + .../export/SYS_IL0000608162C00009__.sql | 11 + .../export/SYS_IL0000609457C00004__.sql | 11 + .../export/SYS_IL0001159131C00010__.sql | 11 + .../export/TRG_A_DEVO_REPLICA_MGMT_MOPDB.sql | 52 + .../TRG_A_DEVO_REPLICA_MGMT_MOPDB_1.sql | 52 + .../TRG_BIU_CHCK_TEMPLATE_TABLE_NAME.sql | 22 + .../TRG_BIU_CHCK_TEMPLATE_TABLE_NAME_1.sql | 22 + .../TRG_BI_A_SOURCE_FILE_CONFIG_CHECK.sql | 59 + .../TRG_BI_A_SOURCE_FILE_CONFIG_CHECK_1.sql | 59 + .../export/TRG_BI_A_SRC_FILE_CFG_ARCH_VAL.sql | 36 + .../TRG_BI_A_SRC_FILE_CFG_ARCH_VAL_1.sql | 36 + .../database/CT_MRDS/export/T_FILENAME.sql | 14 + .../database/CT_MRDS/export/T_FILENAMES.sql | 7 + .../CT_MRDS/export/UK_PKG_VERSION_TRACK.sql | 10 + .../CT_MRDS/export/UK_PKG_VERSION_TRACK_1.sql | 10 + .../database/CT_MRDS/export/UTL_RECOMP.sql | 5 + .../CT_MRDS/export/UTL_RECOMP_ERRORS.sql | 5 + .../CT_MRDS/export/WORKFLOW_MANAGER.sql | 105 + .../CT_MRDS/export/WORKFLOW_MANAGER_1.sql | 221 ++ 113 files changed, 11741 insertions(+) create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_CASPER_FILEVAULT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_PK.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_PK_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_METADATA_INVENTORY.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_METADATA_INVENTORY_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_LOG.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_LOG_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_MOPDB.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_MOPDB_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_TRG.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_TRG_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RQSD.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RQSD_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_SOURCES_IGAM.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_FILE_MANAGER_CONFIG.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_FILE_MANAGER_CONFIG_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_MOPDB_LOAD_HISTORY.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PACKAGE_VERSION_TRACKING.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PACKAGE_VERSION_TRACKING_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PARALLEL_EXPORT_CHUNKS.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PARALLEL_EXPORT_CHUNKS_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PROCESS_LOG.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PROCESS_LOG_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_KEY_SEQ.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_PK.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_PK_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_REFCONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_UQ1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_UQ1_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_KEY_SEQ.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_PK.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_PK_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_REFCONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_UK1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_UK1_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_PK.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_PK_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_HIST.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_HIST_CONSTRAINT.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_KEY_SEQ.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_UK1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_UK1_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_KEY_SEQ.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_SOURCE.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_SOURCE_KEY_SEQ.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_TARGET.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_TARGET_KEY_SEQ.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_2.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_KEY_SEQ.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY_IDX1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY_IDX1_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/CHECK_LINK.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/CT_MRDS.7z create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DATA_EXPORTER.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DATA_EXPORTER_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DBMS_REGISTRY_SYS.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DRARIDMC.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ENV_MANAGER.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ENV_MANAGER_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ERR_LOG.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_ARCHIVER.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_ARCHIVER_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_MANAGER.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_MANAGER_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/Generated-20260302130055.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/M_DWH_ADD_LOAD_INFO_START.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/PK_PARALLEL_EXPORT_CHUNKS.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/PK_PARALLEL_EXPORT_CHUNKS_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C00142356.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C00142356_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062744.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062744_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062752.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062752_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062756.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062756_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062776.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062776_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0000608162C00009__.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0000609457C00004__.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0001159131C00010__.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_A_DEVO_REPLICA_MGMT_MOPDB.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_A_DEVO_REPLICA_MGMT_MOPDB_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BIU_CHCK_TEMPLATE_TABLE_NAME.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BIU_CHCK_TEMPLATE_TABLE_NAME_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SOURCE_FILE_CONFIG_CHECK.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SOURCE_FILE_CONFIG_CHECK_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SRC_FILE_CFG_ARCH_VAL.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SRC_FILE_CFG_ARCH_VAL_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/T_FILENAME.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/T_FILENAMES.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UK_PKG_VERSION_TRACK.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UK_PKG_VERSION_TRACK_1.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UTL_RECOMP.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UTL_RECOMP_ERRORS.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/WORKFLOW_MANAGER.sql create mode 100644 MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/WORKFLOW_MANAGER_1.sql diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_CASPER_FILEVAULT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_CASPER_FILEVAULT.sql new file mode 100644 index 0000000..24345b9 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_CASPER_FILEVAULT.sql @@ -0,0 +1,18 @@ +-------------------------------------------------------- +-- DDL for Table A_CASPER_FILEVAULT +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_CASPER_FILEVAULT" + ( "A_WORKFLOW_HISTORY_KEY" NUMBER(28,0), + "WLA_RUN_ID" NUMBER(28,0), + "WORKFLOW_NAME" CHAR(16 BYTE) COLLATE "USING_NLS_COMP", + "FILENAME" VARCHAR2(250 CHAR) COLLATE "USING_NLS_COMP", + "STATUS" VARCHAR2(30 CHAR) COLLATE "USING_NLS_COMP", + "FILESIZE" NUMBER(28,0), + "FILE_ID" NUMBER(28,0), + "IS_TEST" VARCHAR2(5 CHAR) COLLATE "USING_NLS_COMP", + "REFERENCE_TIME" TIMESTAMP (6) + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION DEFERRED + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT.sql new file mode 100644 index 0000000..e7824da --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT.sql @@ -0,0 +1,19 @@ +-------------------------------------------------------- +-- DDL for Table A_COLUMN_DATE_FORMAT +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_COLUMN_DATE_FORMAT" + ( "TEMPLATE_TABLE_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "COLUMN_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "DATE_FORMAT" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + GRANT DELETE ON "CT_MRDS"."A_COLUMN_DATE_FORMAT" TO "MRDS_LOADER_ROLE"; + GRANT INSERT ON "CT_MRDS"."A_COLUMN_DATE_FORMAT" TO "MRDS_LOADER_ROLE"; + GRANT SELECT ON "CT_MRDS"."A_COLUMN_DATE_FORMAT" TO "MRDS_LOADER_ROLE"; + GRANT UPDATE ON "CT_MRDS"."A_COLUMN_DATE_FORMAT" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_CONSTRAINT.sql new file mode 100644 index 0000000..182c4b3 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_CONSTRAINT.sql @@ -0,0 +1,13 @@ +-------------------------------------------------------- +-- Constraints for Table A_COLUMN_DATE_FORMAT +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_COLUMN_DATE_FORMAT" MODIFY ("TEMPLATE_TABLE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_COLUMN_DATE_FORMAT" MODIFY ("COLUMN_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_COLUMN_DATE_FORMAT" MODIFY ("DATE_FORMAT" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_COLUMN_DATE_FORMAT" ADD CONSTRAINT "A_COLUMN_DATE_FORMAT_PK" PRIMARY KEY ("TEMPLATE_TABLE_NAME", "COLUMN_NAME") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_PK.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_PK.sql new file mode 100644 index 0000000..a45e685 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_PK.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_COLUMN_DATE_FORMAT_PK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_COLUMN_DATE_FORMAT_PK" ON "CT_MRDS"."A_COLUMN_DATE_FORMAT" ("TEMPLATE_TABLE_NAME", "COLUMN_NAME") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_PK_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_PK_1.sql new file mode 100644 index 0000000..a45e685 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_COLUMN_DATE_FORMAT_PK_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_COLUMN_DATE_FORMAT_PK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_COLUMN_DATE_FORMAT_PK" ON "CT_MRDS"."A_COLUMN_DATE_FORMAT" ("TEMPLATE_TABLE_NAME", "COLUMN_NAME") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_METADATA_INVENTORY.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_METADATA_INVENTORY.sql new file mode 100644 index 0000000..af61d40 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_METADATA_INVENTORY.sql @@ -0,0 +1,26 @@ +-------------------------------------------------------- +-- DDL for Table A_DEVO_METADATA_INVENTORY +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_DEVO_METADATA_INVENTORY" + ( "A_VALID_FROM" DATE, + "A_VALID_TO" DATE, + "OWNER" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_NAME" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "COLUMN_NAME" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "DATA_TYPE" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "CHAR_LENGTH" NUMBER, + "DATA_PRECISION" NUMBER, + "DATA_SCALE" NUMBER, + "COLUMN_ID" NUMBER, + "DATA_DESCRIPTION" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", + "LIST_OF_SOURCES" VARCHAR2(20 BYTE) COLLATE "USING_NLS_COMP", + "RAR3_TYPE_OF_ACCESS" CHAR(2 BYTE) COLLATE "USING_NLS_COMP", + "SERVICE_NAME" CHAR(5 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_METADATA_INVENTORY_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_METADATA_INVENTORY_CONSTRAINT.sql new file mode 100644 index 0000000..821cf4f --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_METADATA_INVENTORY_CONSTRAINT.sql @@ -0,0 +1,8 @@ +-------------------------------------------------------- +-- Constraints for Table A_DEVO_METADATA_INVENTORY +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_DEVO_METADATA_INVENTORY" MODIFY ("OWNER" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_METADATA_INVENTORY" MODIFY ("TABLE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_METADATA_INVENTORY" MODIFY ("COLUMN_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_METADATA_INVENTORY" MODIFY ("CHAR_LENGTH" NOT NULL ENABLE); diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_LOG.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_LOG.sql new file mode 100644 index 0000000..6688b55 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_LOG.sql @@ -0,0 +1,26 @@ +-------------------------------------------------------- +-- DDL for Table A_DEVO_REPLICA_MGMT_LOG +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_LOG" + ( "OWNER" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_NAME" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_ALIAS" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "LAST_RUN_ID" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "LAST_START_TIME" DATE, + "LAST_END_TIME" DATE, + "LAST_STATUS" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "SAVE_MODE" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "PARTITION_COLUMN" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "MAX_THREADS" NUMBER(3,0), + "LAST_PROCESSED_KEY" NUMBER(28,10), + "ACTION" VARCHAR2(30 BYTE) COLLATE "USING_NLS_COMP", + "LOG_DATE" DATE, + "LOG_SOURCE" VARCHAR2(30 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_LOG_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_LOG_CONSTRAINT.sql new file mode 100644 index 0000000..cebc699 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_LOG_CONSTRAINT.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- Constraints for Table A_DEVO_REPLICA_MGMT_LOG +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_LOG" MODIFY ("OWNER" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_LOG" MODIFY ("TABLE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_LOG" MODIFY ("TABLE_ALIAS" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_LOG" MODIFY ("SAVE_MODE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_LOG" MODIFY ("PARTITION_COLUMN" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_LOG" MODIFY ("MAX_THREADS" NOT NULL ENABLE); diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_MOPDB.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_MOPDB.sql new file mode 100644 index 0000000..b4960e5 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_MOPDB.sql @@ -0,0 +1,23 @@ +-------------------------------------------------------- +-- DDL for Table A_DEVO_REPLICA_MGMT_MOPDB +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_MOPDB" + ( "OWNER" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_NAME" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_ALIAS" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "LAST_RUN_ID" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "LAST_START_TIME" DATE, + "LAST_END_TIME" DATE, + "LAST_STATUS" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "SAVE_MODE" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "PARTITION_COLUMN" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "MAX_THREADS" NUMBER(3,0), + "LAST_PROCESSED_KEY" NUMBER(28,10) + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_MOPDB_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_MOPDB_CONSTRAINT.sql new file mode 100644 index 0000000..71c0855 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_MOPDB_CONSTRAINT.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- Constraints for Table A_DEVO_REPLICA_MGMT_MOPDB +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_MOPDB" MODIFY ("OWNER" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_MOPDB" MODIFY ("TABLE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_MOPDB" MODIFY ("TABLE_ALIAS" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_MOPDB" MODIFY ("SAVE_MODE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_MOPDB" MODIFY ("PARTITION_COLUMN" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_MOPDB" MODIFY ("MAX_THREADS" NOT NULL ENABLE); diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR.sql new file mode 100644 index 0000000..f7a4dc1 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR.sql @@ -0,0 +1,23 @@ +-------------------------------------------------------- +-- DDL for Table A_DEVO_REPLICA_MGMT_RAR +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR" + ( "OWNER" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_NAME" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_ALIAS" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "LAST_RUN_ID" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "LAST_START_TIME" DATE, + "LAST_END_TIME" DATE, + "LAST_STATUS" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "SAVE_MODE" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "PARTITION_COLUMN" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "MAX_THREADS" NUMBER(3,0), + "LAST_PROCESSED_KEY" NUMBER(28,10) + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_CONSTRAINT.sql new file mode 100644 index 0000000..48438ff --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_CONSTRAINT.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- Constraints for Table A_DEVO_REPLICA_MGMT_RAR +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR" MODIFY ("OWNER" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR" MODIFY ("TABLE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR" MODIFY ("TABLE_ALIAS" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR" MODIFY ("SAVE_MODE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR" MODIFY ("PARTITION_COLUMN" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR" MODIFY ("MAX_THREADS" NOT NULL ENABLE); diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_TRG.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_TRG.sql new file mode 100644 index 0000000..219a7c3 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_TRG.sql @@ -0,0 +1,55 @@ +-------------------------------------------------------- +-- DDL for Trigger A_DEVO_REPLICA_MGMT_RAR_TRG +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR_TRG" +AFTER INSERT OR UPDATE OR DELETE + ON CT_MRDS.A_DEVO_REPLICA_MGMT_RAR + FOR EACH ROW +DECLARE + vAction VARCHAR2(100); +BEGIN + IF INSERTING THEN + vAction := 'INSERT'; + INSERT INTO + CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:NEW.OWNER, :NEW.TABLE_NAME, :NEW.TABLE_ALIAS, + :NEW.LAST_RUN_ID, :NEW.LAST_START_TIME, :NEW.LAST_END_TIME, + :NEW.LAST_STATUS, :NEW.SAVE_MODE, :NEW.PARTITION_COLUMN, + :NEW.MAX_THREADS, :NEW.LAST_PROCESSED_KEY, vAction, + sysdate, 'RAR'); + ELSIF UPDATING THEN + vAction := 'UPDATE'; + INSERT INTO + CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:NEW.OWNER, :NEW.TABLE_NAME, :NEW.TABLE_ALIAS, + :NEW.LAST_RUN_ID, :NEW.LAST_START_TIME, :NEW.LAST_END_TIME, + :NEW.LAST_STATUS, :NEW.SAVE_MODE, :NEW.PARTITION_COLUMN, + :NEW.MAX_THREADS, :NEW.LAST_PROCESSED_KEY, vAction, + sysdate, 'RAR'); + ELSIF DELETING THEN + vAction := 'DELETE'; + INSERT INTO + CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:OLD.OWNER, :OLD.TABLE_NAME, :OLD.TABLE_ALIAS, + :OLD.LAST_RUN_ID, :OLD.LAST_START_TIME, :OLD.LAST_END_TIME, + :OLD.LAST_STATUS, :OLD.SAVE_MODE, :OLD.PARTITION_COLUMN, + :OLD.MAX_THREADS, :OLD.LAST_PROCESSED_KEY, vAction, + sysdate, 'RAR'); + END IF; +END; + +/ +ALTER TRIGGER "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR_TRG" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_TRG_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_TRG_1.sql new file mode 100644 index 0000000..219a7c3 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RAR_TRG_1.sql @@ -0,0 +1,55 @@ +-------------------------------------------------------- +-- DDL for Trigger A_DEVO_REPLICA_MGMT_RAR_TRG +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR_TRG" +AFTER INSERT OR UPDATE OR DELETE + ON CT_MRDS.A_DEVO_REPLICA_MGMT_RAR + FOR EACH ROW +DECLARE + vAction VARCHAR2(100); +BEGIN + IF INSERTING THEN + vAction := 'INSERT'; + INSERT INTO + CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:NEW.OWNER, :NEW.TABLE_NAME, :NEW.TABLE_ALIAS, + :NEW.LAST_RUN_ID, :NEW.LAST_START_TIME, :NEW.LAST_END_TIME, + :NEW.LAST_STATUS, :NEW.SAVE_MODE, :NEW.PARTITION_COLUMN, + :NEW.MAX_THREADS, :NEW.LAST_PROCESSED_KEY, vAction, + sysdate, 'RAR'); + ELSIF UPDATING THEN + vAction := 'UPDATE'; + INSERT INTO + CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:NEW.OWNER, :NEW.TABLE_NAME, :NEW.TABLE_ALIAS, + :NEW.LAST_RUN_ID, :NEW.LAST_START_TIME, :NEW.LAST_END_TIME, + :NEW.LAST_STATUS, :NEW.SAVE_MODE, :NEW.PARTITION_COLUMN, + :NEW.MAX_THREADS, :NEW.LAST_PROCESSED_KEY, vAction, + sysdate, 'RAR'); + ELSIF DELETING THEN + vAction := 'DELETE'; + INSERT INTO + CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:OLD.OWNER, :OLD.TABLE_NAME, :OLD.TABLE_ALIAS, + :OLD.LAST_RUN_ID, :OLD.LAST_START_TIME, :OLD.LAST_END_TIME, + :OLD.LAST_STATUS, :OLD.SAVE_MODE, :OLD.PARTITION_COLUMN, + :OLD.MAX_THREADS, :OLD.LAST_PROCESSED_KEY, vAction, + sysdate, 'RAR'); + END IF; +END; + +/ +ALTER TRIGGER "CT_MRDS"."A_DEVO_REPLICA_MGMT_RAR_TRG" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RQSD.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RQSD.sql new file mode 100644 index 0000000..5b2d4e1 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RQSD.sql @@ -0,0 +1,23 @@ +-------------------------------------------------------- +-- DDL for Table A_DEVO_REPLICA_MGMT_RQSD +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RQSD" + ( "OWNER" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_NAME" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_ALIAS" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "LAST_RUN_ID" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "LAST_START_TIME" DATE, + "LAST_END_TIME" DATE, + "LAST_STATUS" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "SAVE_MODE" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "PARTITION_COLUMN" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", + "MAX_THREADS" NUMBER(3,0), + "LAST_PROCESSED_KEY" NUMBER(28,10) + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RQSD_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RQSD_CONSTRAINT.sql new file mode 100644 index 0000000..74e28e9 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_REPLICA_MGMT_RQSD_CONSTRAINT.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- Constraints for Table A_DEVO_REPLICA_MGMT_RQSD +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RQSD" MODIFY ("OWNER" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RQSD" MODIFY ("TABLE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RQSD" MODIFY ("TABLE_ALIAS" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RQSD" MODIFY ("SAVE_MODE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RQSD" MODIFY ("PARTITION_COLUMN" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_DEVO_REPLICA_MGMT_RQSD" MODIFY ("MAX_THREADS" NOT NULL ENABLE); diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_SOURCES_IGAM.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_SOURCES_IGAM.sql new file mode 100644 index 0000000..eca0e5a --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_DEVO_SOURCES_IGAM.sql @@ -0,0 +1,17 @@ +-------------------------------------------------------- +-- DDL for Table A_DEVO_SOURCES_IGAM +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_DEVO_SOURCES_IGAM" + ( "ENVIRONMENT" VARCHAR2(100 BYTE) COLLATE "USING_NLS_COMP", + "MRDS_SOURCE" VARCHAR2(30 BYTE) COLLATE "USING_NLS_COMP", + "MRDS_SUBSOURCE_ID" VARCHAR2(30 BYTE) COLLATE "USING_NLS_COMP", + "MRDS_ENTITLEMENT" VARCHAR2(100 BYTE) COLLATE "USING_NLS_COMP", + "SERVICE_NAME" VARCHAR2(5 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_FILE_MANAGER_CONFIG.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_FILE_MANAGER_CONFIG.sql new file mode 100644 index 0000000..4be12e0 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_FILE_MANAGER_CONFIG.sql @@ -0,0 +1,16 @@ +-------------------------------------------------------- +-- DDL for Table A_FILE_MANAGER_CONFIG +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_FILE_MANAGER_CONFIG" + ( "ENVIRONMENT_ID" VARCHAR2(100 BYTE) COLLATE "USING_NLS_COMP", + "CONFIG_VARIABLE" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "CONFIG_VARIABLE_VALUE" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "CONFIG_VARIABLE_COMMENT" VARCHAR2(600 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_FILE_MANAGER_CONFIG_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_FILE_MANAGER_CONFIG_CONSTRAINT.sql new file mode 100644 index 0000000..a536c49 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_FILE_MANAGER_CONFIG_CONSTRAINT.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- Constraints for Table A_FILE_MANAGER_CONFIG +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_FILE_MANAGER_CONFIG" ADD PRIMARY KEY ("ENVIRONMENT_ID", "CONFIG_VARIABLE") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_MOPDB_LOAD_HISTORY.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_MOPDB_LOAD_HISTORY.sql new file mode 100644 index 0000000..0622577 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_MOPDB_LOAD_HISTORY.sql @@ -0,0 +1,24 @@ +-------------------------------------------------------- +-- DDL for View A_MOPDB_LOAD_HISTORY +-------------------------------------------------------- + + CREATE OR REPLACE FORCE EDITIONABLE VIEW "CT_MRDS"."A_MOPDB_LOAD_HISTORY" ("A_WORKFLOW_HISTORY_KEY", "A_WORKFLOW_HISTORY_SOURCE_KEY", "A_TASK_HISTORY_KEY", "TASK_NAME", "TASK_START", "TASK_END", "WORKFLOW_SUCCESSFUL") DEFAULT COLLATION "USING_NLS_COMP" AS + SELECT distinct wh.a_workflow_history_key, + ths.a_workflow_history_source_key, + th.a_task_history_key, + th.task_name, + th.task_start, + th.task_end, + wh.workflow_successful + FROM CT_MRDS.A_WORKFLOW_HISTORY wh + JOIN CT_MRDS.A_TASK_HISTORY th + ON wh.a_workflow_history_key = th.a_workflow_history_key + AND wh.service_name = th.service_name + JOIN CT_MRDS.A_TASK_HISTORY_SOURCE ths + ON th.a_task_history_key = ths.a_task_history_key + AND th.service_name = ths.service_name + WHERE wh.service_name = 'MOPDB' + AND wh.workflow_successful = 'Y' + AND lower(th.task_name) not like '%_sq' + AND ths.a_workflow_history_source_key is not null +; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PACKAGE_VERSION_TRACKING.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PACKAGE_VERSION_TRACKING.sql new file mode 100644 index 0000000..b0ba580 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PACKAGE_VERSION_TRACKING.sql @@ -0,0 +1,35 @@ +-------------------------------------------------------- +-- DDL for Table A_PACKAGE_VERSION_TRACKING +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" + ( "A_PACKAGE_VERSION_TRACKING_KEY" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE , + "PACKAGE_OWNER" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "PACKAGE_NAME" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "PACKAGE_TYPE" VARCHAR2(20 BYTE) COLLATE "USING_NLS_COMP", + "PACKAGE_VERSION" VARCHAR2(10 BYTE) COLLATE "USING_NLS_COMP", + "PACKAGE_BUILD_DATE" VARCHAR2(20 BYTE) COLLATE "USING_NLS_COMP", + "PACKAGE_AUTHOR" VARCHAR2(100 BYTE) COLLATE "USING_NLS_COMP", + "SOURCE_CODE_HASH_SPEC" VARCHAR2(64 BYTE) COLLATE "USING_NLS_COMP", + "SOURCE_CODE_HASH_BODY" VARCHAR2(64 BYTE) COLLATE "USING_NLS_COMP", + "LINE_COUNT_SPEC" NUMBER, + "LINE_COUNT_BODY" NUMBER, + "DETECTED_CHANGE_WITHOUT_VERSION" CHAR(1 BYTE) COLLATE "USING_NLS_COMP" DEFAULT 'N', + "CHANGE_DETECTION_MESSAGE" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", + "TRACKING_DATE" TIMESTAMP (6) DEFAULT SYSTIMESTAMP, + "TRACKED_BY_USER" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP" DEFAULT USER, + "TRACKED_BY_MODULE" VARCHAR2(64 BYTE) COLLATE "USING_NLS_COMP" DEFAULT SYS_CONTEXT('USERENV','MODULE') + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + + COMMENT ON COLUMN "CT_MRDS"."A_PACKAGE_VERSION_TRACKING"."SOURCE_CODE_HASH_SPEC" IS 'SHA256 hash of package specification source code'; + COMMENT ON COLUMN "CT_MRDS"."A_PACKAGE_VERSION_TRACKING"."SOURCE_CODE_HASH_BODY" IS 'SHA256 hash of package body source code'; + COMMENT ON COLUMN "CT_MRDS"."A_PACKAGE_VERSION_TRACKING"."DETECTED_CHANGE_WITHOUT_VERSION" IS 'Y if source hash changed but version did not'; + COMMENT ON COLUMN "CT_MRDS"."A_PACKAGE_VERSION_TRACKING"."CHANGE_DETECTION_MESSAGE" IS 'Details about detected changes without version update'; + COMMENT ON TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" IS 'Tracks package version history and source code hashes for change detection'; + GRANT SELECT ON "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" TO "MRDS_LOADER"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PACKAGE_VERSION_TRACKING_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PACKAGE_VERSION_TRACKING_CONSTRAINT.sql new file mode 100644 index 0000000..83c30cc --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PACKAGE_VERSION_TRACKING_CONSTRAINT.sql @@ -0,0 +1,24 @@ +-------------------------------------------------------- +-- Constraints for Table A_PACKAGE_VERSION_TRACKING +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" MODIFY ("A_PACKAGE_VERSION_TRACKING_KEY" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" MODIFY ("PACKAGE_OWNER" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" MODIFY ("PACKAGE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" MODIFY ("PACKAGE_TYPE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" MODIFY ("TRACKING_DATE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" MODIFY ("TRACKED_BY_USER" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" ADD CHECK (PACKAGE_TYPE IN ('SPEC', 'BODY', 'BOTH')) ENABLE; + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" ADD CHECK (DETECTED_CHANGE_WITHOUT_VERSION IN ('Y', 'N')) ENABLE; + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" ADD PRIMARY KEY ("A_PACKAGE_VERSION_TRACKING_KEY") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; + ALTER TABLE "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" ADD CONSTRAINT "UK_PKG_VERSION_TRACK" UNIQUE ("PACKAGE_OWNER", "PACKAGE_NAME", "TRACKING_DATE") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PARALLEL_EXPORT_CHUNKS.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PARALLEL_EXPORT_CHUNKS.sql new file mode 100644 index 0000000..2fdf1dc --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PARALLEL_EXPORT_CHUNKS.sql @@ -0,0 +1,58 @@ +-------------------------------------------------------- +-- DDL for Table A_PARALLEL_EXPORT_CHUNKS +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" + ( "CHUNK_ID" NUMBER, + "TASK_NAME" VARCHAR2(100 BYTE) COLLATE "USING_NLS_COMP", + "YEAR_VALUE" VARCHAR2(4 BYTE) COLLATE "USING_NLS_COMP", + "MONTH_VALUE" VARCHAR2(2 BYTE) COLLATE "USING_NLS_COMP", + "SCHEMA_NAME" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_NAME" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "KEY_COLUMN_NAME" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "BUCKET_URI" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", + "FOLDER_NAME" VARCHAR2(1000 BYTE) COLLATE "USING_NLS_COMP", + "PROCESSED_COLUMNS" VARCHAR2(32767 BYTE) COLLATE "USING_NLS_COMP", + "MIN_DATE" DATE, + "MAX_DATE" DATE, + "CREDENTIAL_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "FORMAT_TYPE" VARCHAR2(20 BYTE) COLLATE "USING_NLS_COMP", + "FILE_BASE_NAME" VARCHAR2(1000 BYTE) COLLATE "USING_NLS_COMP", + "TEMPLATE_TABLE_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "MAX_FILE_SIZE" NUMBER DEFAULT 104857600, + "JOB_CLASS" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "STATUS" VARCHAR2(30 BYTE) COLLATE "USING_NLS_COMP" DEFAULT 'PENDING', + "ERROR_MESSAGE" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", + "EXPORT_TIMESTAMP" TIMESTAMP (6), + "CREATED_DATE" TIMESTAMP (6) DEFAULT SYSTIMESTAMP + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."CHUNK_ID" IS 'Chunk identifier within task (partition number) - unique per TASK_NAME, not globally'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."TASK_NAME" IS 'DBMS_PARALLEL_EXECUTE task name - session isolation key, part of composite PK with CHUNK_ID'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."YEAR_VALUE" IS 'Partition year (YYYY)'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."MONTH_VALUE" IS 'Partition month (MM)'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."SCHEMA_NAME" IS 'Schema owning the source table'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."TABLE_NAME" IS 'Source table name for export'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."KEY_COLUMN_NAME" IS 'Key column for load history join'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."BUCKET_URI" IS 'OCI bucket URI for export destination'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."FOLDER_NAME" IS 'Folder name within bucket'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."PROCESSED_COLUMNS" IS 'Comma-separated list of columns to export'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."MIN_DATE" IS 'Minimum date filter for partition'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."MAX_DATE" IS 'Maximum date filter for partition'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."CREDENTIAL_NAME" IS 'OCI credential name for authentication'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."FORMAT_TYPE" IS 'Export format: PARQUET or CSV'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."FILE_BASE_NAME" IS 'Base filename for CSV exports (NULL for Parquet)'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."TEMPLATE_TABLE_NAME" IS 'Template table name for per-column date format configuration (e.g., CT_ET_TEMPLATES.TABLE_NAME)'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."MAX_FILE_SIZE" IS 'Maximum file size in bytes for CSV exports only (e.g., 104857600 = 100MB, 1073741824 = 1GB) - default 100MB (104857600). NOTE: Not applicable for PARQUET format (Oracle limitation)'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."JOB_CLASS" IS 'Oracle Scheduler job class name for resource management (e.g., ''high'', ''DEFAULT_JOB_CLASS'') - NULL uses default scheduler priority'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."STATUS" IS 'Chunk processing status: PENDING (not started), PROCESSING (in progress), COMPLETED (success), FAILED (error) - allows retry of failed partitions only'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."ERROR_MESSAGE" IS 'Error message if chunk processing failed (STATUS = FAILED)'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."EXPORT_TIMESTAMP" IS 'Timestamp when chunk export was completed (STATUS = COMPLETED)'; + COMMENT ON COLUMN "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS"."CREATED_DATE" IS 'Timestamp when chunk was created'; + COMMENT ON TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" IS 'Permanent table for parallel export chunk processing (DBMS_PARALLEL_EXECUTE) - permanent because GTT data not visible in parallel callback sessions. PK: (TASK_NAME, CHUNK_ID) ensures session isolation for concurrent exports.'; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PARALLEL_EXPORT_CHUNKS_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PARALLEL_EXPORT_CHUNKS_CONSTRAINT.sql new file mode 100644 index 0000000..a49a1f8 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PARALLEL_EXPORT_CHUNKS_CONSTRAINT.sql @@ -0,0 +1,26 @@ +-------------------------------------------------------- +-- Constraints for Table A_PARALLEL_EXPORT_CHUNKS +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("CHUNK_ID" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("TASK_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("YEAR_VALUE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("MONTH_VALUE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("SCHEMA_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("TABLE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("KEY_COLUMN_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("BUCKET_URI" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("FOLDER_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("MIN_DATE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("MAX_DATE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("CREDENTIAL_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("FORMAT_TYPE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("MAX_FILE_SIZE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("STATUS" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" MODIFY ("CREATED_DATE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" ADD CONSTRAINT "PK_PARALLEL_EXPORT_CHUNKS" PRIMARY KEY ("TASK_NAME", "CHUNK_ID") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PROCESS_LOG.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PROCESS_LOG.sql new file mode 100644 index 0000000..195ae62 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PROCESS_LOG.sql @@ -0,0 +1,24 @@ +-------------------------------------------------------- +-- DDL for Table A_PROCESS_LOG +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_PROCESS_LOG" + ( "A_PROCESS_LOG_KEY" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE , + "GUID" VARCHAR2(32 BYTE) COLLATE "USING_NLS_COMP", + "USERNAME" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "OSUSER" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "MACHINE" VARCHAR2(64 BYTE) COLLATE "USING_NLS_COMP", + "MODULE" VARCHAR2(64 BYTE) COLLATE "USING_NLS_COMP", + "PROCESS_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "PROCEDURE_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "PROCEDURE_PARAMETERS" VARCHAR2(20000 BYTE) COLLATE "USING_NLS_COMP", + "LOG_LEVEL" VARCHAR2(10 BYTE) COLLATE "USING_NLS_COMP", + "LOG_MESSAGE" VARCHAR2(20000 BYTE) COLLATE "USING_NLS_COMP", + "LOG_TIMESTAMP" TIMESTAMP (6) DEFAULT SYSTIMESTAMP + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PROCESS_LOG_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PROCESS_LOG_CONSTRAINT.sql new file mode 100644 index 0000000..5ac1ff7 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_PROCESS_LOG_CONSTRAINT.sql @@ -0,0 +1,11 @@ +-------------------------------------------------------- +-- Constraints for Table A_PROCESS_LOG +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_PROCESS_LOG" MODIFY ("A_PROCESS_LOG_KEY" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_PROCESS_LOG" ADD PRIMARY KEY ("A_PROCESS_LOG_KEY") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE.sql new file mode 100644 index 0000000..2da9842 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE.sql @@ -0,0 +1,18 @@ +-------------------------------------------------------- +-- DDL for Table A_SOURCE +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_SOURCE" + ( "A_SOURCE_KEY" VARCHAR2(30 BYTE) COLLATE "USING_NLS_COMP", + "SOURCE_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + GRANT DELETE ON "CT_MRDS"."A_SOURCE" TO "MRDS_LOADER_ROLE"; + GRANT INSERT ON "CT_MRDS"."A_SOURCE" TO "MRDS_LOADER_ROLE"; + GRANT SELECT ON "CT_MRDS"."A_SOURCE" TO "MRDS_LOADER_ROLE"; + GRANT UPDATE ON "CT_MRDS"."A_SOURCE" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_CONSTRAINT.sql new file mode 100644 index 0000000..b71a26e --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_CONSTRAINT.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- Constraints for Table A_SOURCE +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_SOURCE" ADD CONSTRAINT "A_SOURCE_PK" PRIMARY KEY ("A_SOURCE_KEY") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG.sql new file mode 100644 index 0000000..90f431b --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG.sql @@ -0,0 +1,61 @@ +-------------------------------------------------------- +-- DDL for Table A_SOURCE_FILE_CONFIG +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" + ( "A_SOURCE_FILE_CONFIG_KEY" NUMBER(38,0), + "A_SOURCE_KEY" VARCHAR2(30 BYTE) COLLATE "USING_NLS_COMP", + "SOURCE_FILE_TYPE" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "SOURCE_FILE_ID" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "SOURCE_FILE_DESC" VARCHAR2(2000 BYTE) COLLATE "USING_NLS_COMP", + "SOURCE_FILE_NAME_PATTERN" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "TABLE_ID" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "TEMPLATE_TABLE_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "CONTAINER_FILE_KEY" NUMBER(38,0), + "ARCHIVE_THRESHOLD_DAYS" NUMBER(4,0), + "ARCHIVE_THRESHOLD_FILES_COUNT" NUMBER(38,0), + "ARCHIVE_THRESHOLD_BYTES_SUM" NUMBER(38,0), + "ODS_SCHEMA_NAME" VARCHAR2(100 BYTE) COLLATE "USING_NLS_COMP", + "ARCHIVE_THRESHOLD_ROWS_COUNT" NUMBER(38,0), + "HOURS_TO_EXPIRE_STATISTICS" NUMBER(38,3), + "ENCODING" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP" DEFAULT 'UTF8', + "ARCHIVE_ENABLED" CHAR(1 BYTE) COLLATE "USING_NLS_COMP" DEFAULT 'N', + "KEEP_IN_TRASH" CHAR(1 BYTE) COLLATE "USING_NLS_COMP" DEFAULT 'Y', + "ARCHIVAL_STRATEGY" VARCHAR2(30 BYTE) COLLATE "USING_NLS_COMP" DEFAULT 'THRESHOLD_BASED', + "MINIMUM_AGE_MONTHS" NUMBER(3,0) DEFAULT NULL, + "IS_ARCHIVE_ENABLED" CHAR(1 BYTE) COLLATE "USING_NLS_COMP" DEFAULT 'N', + "IS_KEEP_IN_TRASH" CHAR(1 BYTE) COLLATE "USING_NLS_COMP" DEFAULT 'Y' + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."A_SOURCE_FILE_CONFIG_KEY" IS 'Primary key - unique identifier for source file configuration record'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."A_SOURCE_KEY" IS 'Foreign key to A_SOURCE table - identifies the source system (e.g., LM, C2D, CSDB)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."SOURCE_FILE_TYPE" IS 'Type of file configuration: INPUT (data files), CONTAINER (xml files), or LOAD_CONFIG (configuration files)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."SOURCE_FILE_ID" IS 'Unique identifier for the source file within the source system (e.g., UC_DISSEM, STANDING_FACILITIES)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."SOURCE_FILE_DESC" IS 'Human-readable description of the source file and its purpose'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."SOURCE_FILE_NAME_PATTERN" IS 'Filename pattern for matching incoming files (supports wildcards, e.g., UC_NMA_DISSEM-*.csv)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."TABLE_ID" IS 'Identifier for the target table where data will be loaded (without schema prefix)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."TEMPLATE_TABLE_NAME" IS 'Fully qualified name of template table in CT_ET_TEMPLATES schema used for external table creation'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."CONTAINER_FILE_KEY" IS 'Foreign key to parent container configuration when this file is part of an xml (NULL for standalone files)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."ARCHIVE_THRESHOLD_DAYS" IS 'Threshold for THRESHOLD_BASED strategy: archive data older than N days'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."ARCHIVE_THRESHOLD_FILES_COUNT" IS 'Trigger archival when file count exceeds this threshold (used in THRESHOLD_BASED and HYBRID strategies)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."ARCHIVE_THRESHOLD_BYTES_SUM" IS 'Trigger archival when total size in bytes exceeds this threshold (used in THRESHOLD_BASED and HYBRID strategies)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."ODS_SCHEMA_NAME" IS 'Schema name where ODS external tables are created (typically ODS)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."ARCHIVE_THRESHOLD_ROWS_COUNT" IS 'Trigger archival when total row count exceeds this threshold (used in THRESHOLD_BASED and HYBRID strategies)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."HOURS_TO_EXPIRE_STATISTICS" IS 'Number of hours before table statistics expire and need to be recalculated'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."ENCODING" IS 'Oracle character set name for CSV files (e.g., UTF8, WE8MSWIN1252, EE8ISO8859P2)'; + 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'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."ARCHIVAL_STRATEGY" IS 'Archival strategy: THRESHOLD_BASED (days-based), MINIMUM_AGE_MONTHS (0=current month, N=retain N months), HYBRID (combination)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."MINIMUM_AGE_MONTHS" IS 'Minimum age in months before archival (required for MINIMUM_AGE_MONTHS and HYBRID strategies, 0=current month only)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."IS_ARCHIVE_ENABLED" IS 'Y=Enable archiving, N=Skip archiving. Controls if table participates in archival process'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_CONFIG"."IS_KEEP_IN_TRASH" IS 'Y=Keep files in TRASH after archiving, N=Delete immediately. Controls TRASH retention policy'; + GRANT DELETE ON "CT_MRDS"."A_SOURCE_FILE_CONFIG" TO "MRDS_LOADER_ROLE"; + GRANT INSERT ON "CT_MRDS"."A_SOURCE_FILE_CONFIG" TO "MRDS_LOADER_ROLE"; + GRANT SELECT ON "CT_MRDS"."A_SOURCE_FILE_CONFIG" TO "MRDS_LOADER_ROLE"; + GRANT UPDATE ON "CT_MRDS"."A_SOURCE_FILE_CONFIG" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_CONSTRAINT.sql new file mode 100644 index 0000000..35c6447 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_CONSTRAINT.sql @@ -0,0 +1,31 @@ +-------------------------------------------------------- +-- Constraints for Table A_SOURCE_FILE_CONFIG +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" MODIFY ("A_SOURCE_FILE_CONFIG_KEY" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" MODIFY ("A_SOURCE_KEY" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "A_SOURCE_FILE_CONFIG_PK" PRIMARY KEY ("A_SOURCE_FILE_CONFIG_KEY") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "SOURCE_FILE_TYPE_CHK" CHECK (SOURCE_FILE_TYPE IN ('INPUT', 'CONTAINER', 'LOAD_CONFIG')) ENABLE; + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "A_SOURCE_FILE_CONFIG_UQ1" UNIQUE ("SOURCE_FILE_TYPE", "SOURCE_FILE_ID", "TABLE_ID") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "CHK_ARCHIVAL_STRATEGY" CHECK ( + ARCHIVAL_STRATEGY IN ('THRESHOLD_BASED', 'MINIMUM_AGE_MONTHS', 'HYBRID') + ) ENABLE; + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" MODIFY ("ARCHIVE_ENABLED" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" MODIFY ("KEEP_IN_TRASH" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" MODIFY ("ARCHIVAL_STRATEGY" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "CHK_ARCHIVE_ENABLED" CHECK (ARCHIVE_ENABLED IN ('Y', 'N')) ENABLE; + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "CHK_KEEP_IN_TRASH" CHECK (KEEP_IN_TRASH IN ('Y', 'N')) ENABLE; + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" MODIFY ("IS_ARCHIVE_ENABLED" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" MODIFY ("IS_KEEP_IN_TRASH" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "CHK_IS_ARCHIVE_ENABLED" CHECK (IS_ARCHIVE_ENABLED IN ('Y', 'N')) ENABLE; + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "CHK_IS_KEEP_IN_TRASH" CHECK (IS_KEEP_IN_TRASH IN ('Y', 'N')) ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_KEY_SEQ.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_KEY_SEQ.sql new file mode 100644 index 0000000..f6b7231 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_KEY_SEQ.sql @@ -0,0 +1,6 @@ +-------------------------------------------------------- +-- DDL for Sequence A_SOURCE_FILE_CONFIG_KEY_SEQ +-------------------------------------------------------- + + CREATE SEQUENCE "CT_MRDS"."A_SOURCE_FILE_CONFIG_KEY_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 843 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL ; + GRANT SELECT ON "CT_MRDS"."A_SOURCE_FILE_CONFIG_KEY_SEQ" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_PK.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_PK.sql new file mode 100644 index 0000000..1e3c7cf --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_PK.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_FILE_CONFIG_PK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_FILE_CONFIG_PK" ON "CT_MRDS"."A_SOURCE_FILE_CONFIG" ("A_SOURCE_FILE_CONFIG_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_PK_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_PK_1.sql new file mode 100644 index 0000000..1e3c7cf --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_PK_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_FILE_CONFIG_PK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_FILE_CONFIG_PK" ON "CT_MRDS"."A_SOURCE_FILE_CONFIG" ("A_SOURCE_FILE_CONFIG_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_REFCONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_REFCONSTRAINT.sql new file mode 100644 index 0000000..518519d --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_REFCONSTRAINT.sql @@ -0,0 +1,8 @@ +-------------------------------------------------------- +-- Ref Constraints for Table A_SOURCE_FILE_CONFIG +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "ASFC_A_SOURCE_KEY_FK" FOREIGN KEY ("A_SOURCE_KEY") + REFERENCES "CT_MRDS"."A_SOURCE" ("A_SOURCE_KEY") ENABLE; + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_CONFIG" ADD CONSTRAINT "ASFC_CONTAINER_FILE_KEY_FK" FOREIGN KEY ("CONTAINER_FILE_KEY") + REFERENCES "CT_MRDS"."A_SOURCE_FILE_CONFIG" ("A_SOURCE_FILE_CONFIG_KEY") ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_UQ1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_UQ1.sql new file mode 100644 index 0000000..238d18f --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_UQ1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_FILE_CONFIG_UQ1 +-------------------------------------------------------- + + 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") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_UQ1_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_UQ1_1.sql new file mode 100644 index 0000000..238d18f --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_CONFIG_UQ1_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_FILE_CONFIG_UQ1 +-------------------------------------------------------- + + 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") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED.sql new file mode 100644 index 0000000..000851a --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED.sql @@ -0,0 +1,43 @@ +-------------------------------------------------------- +-- DDL for Table A_SOURCE_FILE_RECEIVED +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_SOURCE_FILE_RECEIVED" + ( "A_SOURCE_FILE_RECEIVED_KEY" NUMBER(38,0), + "A_SOURCE_FILE_CONFIG_KEY" NUMBER(38,0), + "SOURCE_FILE_NAME" VARCHAR2(1000 BYTE) COLLATE "USING_NLS_COMP", + "CHECKSUM" VARCHAR2(128 BYTE) COLLATE "USING_NLS_COMP", + "CREATED" TIMESTAMP (6) WITH TIME ZONE, + "BYTES" NUMBER, + "RECEPTION_DATE" DATE, + "PROCESSING_STATUS" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "EXTERNAL_TABLE_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "PARTITION_YEAR" VARCHAR2(4 BYTE) COLLATE "USING_NLS_COMP", + "PARTITION_MONTH" VARCHAR2(2 BYTE) COLLATE "USING_NLS_COMP", + "ARCH_PATH" VARCHAR2(1000 BYTE) COLLATE "USING_NLS_COMP", + "PROCESS_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."A_SOURCE_FILE_RECEIVED_KEY" IS 'Primary key - unique identifier for received file record'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."A_SOURCE_FILE_CONFIG_KEY" IS 'Foreign key to A_SOURCE_FILE_CONFIG - links file to its configuration and processing rules'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."SOURCE_FILE_NAME" IS 'Full object name/path of the received file in OCI Object Storage (includes INBOX prefix)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."CHECKSUM" IS 'MD5 checksum of file content for integrity verification and duplicate detection'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."CREATED" IS 'Timestamp with timezone when file was created/uploaded to Object Storage (from DBMS_CLOUD.LIST_OBJECTS)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."BYTES" IS 'File size in bytes'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."RECEPTION_DATE" IS 'Date when file was registered in the system (extracted from CREATED timestamp)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."PROCESSING_STATUS" IS 'File processing status: RECEIVED ? VALIDATED ? READY_FOR_INGESTION ? INGESTED ? ARCHIVED_AND_TRASHED ? ARCHIVED_AND_PURGED (optional)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."EXTERNAL_TABLE_NAME" IS 'Name of temporary external table created for file validation (dropped after validation)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."PARTITION_YEAR" IS 'Year partition value (YYYY format) when file was archived to ARCHIVE bucket with Hive-style partitioning'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."PARTITION_MONTH" IS 'Month partition value (MM format) when file was archived to ARCHIVE bucket with Hive-style partitioning'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."ARCH_PATH" IS 'Archive directory prefix in ARCHIVE bucket containing archived Parquet files (supports multiple files from parallel DBMS_CLOUD.EXPORT_DATA)'; + COMMENT ON COLUMN "CT_MRDS"."A_SOURCE_FILE_RECEIVED"."PROCESS_NAME" IS 'Name of the process that created this record'; + GRANT DELETE ON "CT_MRDS"."A_SOURCE_FILE_RECEIVED" TO "MRDS_LOADER_ROLE"; + GRANT INSERT ON "CT_MRDS"."A_SOURCE_FILE_RECEIVED" TO "MRDS_LOADER_ROLE"; + GRANT SELECT ON "CT_MRDS"."A_SOURCE_FILE_RECEIVED" TO "MRDS_LOADER_ROLE"; + GRANT UPDATE ON "CT_MRDS"."A_SOURCE_FILE_RECEIVED" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_CONSTRAINT.sql new file mode 100644 index 0000000..19dfe2d --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_CONSTRAINT.sql @@ -0,0 +1,24 @@ +-------------------------------------------------------- +-- Constraints for Table A_SOURCE_FILE_RECEIVED +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_RECEIVED" MODIFY ("A_SOURCE_FILE_RECEIVED_KEY" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_RECEIVED" MODIFY ("A_SOURCE_FILE_CONFIG_KEY" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_RECEIVED" MODIFY ("SOURCE_FILE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_RECEIVED" MODIFY ("RECEPTION_DATE" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_RECEIVED" ADD CONSTRAINT "A_SOURCE_FILE_RECEIVED_PK" PRIMARY KEY ("A_SOURCE_FILE_RECEIVED_KEY") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; + 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 + )) ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_KEY_SEQ.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_KEY_SEQ.sql new file mode 100644 index 0000000..afe2e68 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_KEY_SEQ.sql @@ -0,0 +1,6 @@ +-------------------------------------------------------- +-- DDL for Sequence A_SOURCE_FILE_RECEIVED_KEY_SEQ +-------------------------------------------------------- + + CREATE SEQUENCE "CT_MRDS"."A_SOURCE_FILE_RECEIVED_KEY_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 3851 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL ; + GRANT SELECT ON "CT_MRDS"."A_SOURCE_FILE_RECEIVED_KEY_SEQ" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_PK.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_PK.sql new file mode 100644 index 0000000..b37005a --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_PK.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_FILE_RECEIVED_PK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_FILE_RECEIVED_PK" ON "CT_MRDS"."A_SOURCE_FILE_RECEIVED" ("A_SOURCE_FILE_RECEIVED_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_PK_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_PK_1.sql new file mode 100644 index 0000000..b37005a --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_PK_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_FILE_RECEIVED_PK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_FILE_RECEIVED_PK" ON "CT_MRDS"."A_SOURCE_FILE_RECEIVED" ("A_SOURCE_FILE_RECEIVED_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_REFCONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_REFCONSTRAINT.sql new file mode 100644 index 0000000..0025dfa --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_REFCONSTRAINT.sql @@ -0,0 +1,6 @@ +-------------------------------------------------------- +-- Ref Constraints for Table A_SOURCE_FILE_RECEIVED +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_SOURCE_FILE_RECEIVED" ADD 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") ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_UK1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_UK1.sql new file mode 100644 index 0000000..e571427 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_UK1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_FILE_RECEIVED_UK1 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_FILE_RECEIVED_UK1" ON "CT_MRDS"."A_SOURCE_FILE_RECEIVED" ("CHECKSUM", SYS_EXTRACT_UTC("CREATED"), "BYTES") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_UK1_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_UK1_1.sql new file mode 100644 index 0000000..e571427 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_FILE_RECEIVED_UK1_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_FILE_RECEIVED_UK1 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_FILE_RECEIVED_UK1" ON "CT_MRDS"."A_SOURCE_FILE_RECEIVED" ("CHECKSUM", SYS_EXTRACT_UTC("CREATED"), "BYTES") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_PK.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_PK.sql new file mode 100644 index 0000000..3b22f41 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_PK.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_PK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_PK" ON "CT_MRDS"."A_SOURCE" ("A_SOURCE_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_PK_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_PK_1.sql new file mode 100644 index 0000000..3b22f41 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_SOURCE_PK_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_SOURCE_PK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_SOURCE_PK" ON "CT_MRDS"."A_SOURCE" ("A_SOURCE_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT.sql new file mode 100644 index 0000000..2ebd715 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT.sql @@ -0,0 +1,23 @@ +-------------------------------------------------------- +-- DDL for Table A_TABLE_STAT +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_TABLE_STAT" + ( "A_TABLE_STAT_KEY" NUMBER(38,0), + "A_SOURCE_FILE_CONFIG_KEY" NUMBER(38,0), + "TABLE_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "FILE_COUNT" NUMBER(38,0), + "OVER_ARCH_THRESOLD_FILE_COUNT" NUMBER(38,0), + "ROW_COUNT" NUMBER(38,0), + "OVER_ARCH_THRESOLD_ROW_COUNT" NUMBER(38,0), + "SIZE" NUMBER(38,0), + "OVER_ARCH_THRESOLD_SIZE" NUMBER(38,0), + "ARCH_THRESHOLD_DAYS" NUMBER(4,0), + "CREATED" TIMESTAMP (6) DEFAULT systimestamp + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_CONSTRAINT.sql new file mode 100644 index 0000000..229be0f --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_CONSTRAINT.sql @@ -0,0 +1,18 @@ +-------------------------------------------------------- +-- Constraints for Table A_TABLE_STAT +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_TABLE_STAT" MODIFY ("A_SOURCE_FILE_CONFIG_KEY" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_TABLE_STAT" MODIFY ("TABLE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_TABLE_STAT" ADD PRIMARY KEY ("A_TABLE_STAT_KEY") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; + ALTER TABLE "CT_MRDS"."A_TABLE_STAT" ADD CONSTRAINT "A_TABLE_STAT_UK1" UNIQUE ("A_SOURCE_FILE_CONFIG_KEY") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_HIST.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_HIST.sql new file mode 100644 index 0000000..4c1d275 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_HIST.sql @@ -0,0 +1,23 @@ +-------------------------------------------------------- +-- DDL for Table A_TABLE_STAT_HIST +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_TABLE_STAT_HIST" + ( "A_TABLE_STAT_HIST_KEY" NUMBER(38,0), + "A_SOURCE_FILE_CONFIG_KEY" NUMBER(38,0), + "TABLE_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "FILE_COUNT" NUMBER(38,0), + "OVER_ARCH_THRESOLD_FILE_COUNT" NUMBER(38,0), + "ROW_COUNT" NUMBER(38,0), + "OVER_ARCH_THRESOLD_ROW_COUNT" NUMBER(38,0), + "SIZE" NUMBER(38,0), + "OVER_ARCH_THRESOLD_SIZE" NUMBER(38,0), + "ARCH_THRESHOLD_DAYS" NUMBER(4,0), + "CREATED" TIMESTAMP (6) DEFAULT systimestamp + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_HIST_CONSTRAINT.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_HIST_CONSTRAINT.sql new file mode 100644 index 0000000..44b7db4 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_HIST_CONSTRAINT.sql @@ -0,0 +1,12 @@ +-------------------------------------------------------- +-- Constraints for Table A_TABLE_STAT_HIST +-------------------------------------------------------- + + ALTER TABLE "CT_MRDS"."A_TABLE_STAT_HIST" MODIFY ("A_SOURCE_FILE_CONFIG_KEY" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_TABLE_STAT_HIST" MODIFY ("TABLE_NAME" NOT NULL ENABLE); + ALTER TABLE "CT_MRDS"."A_TABLE_STAT_HIST" ADD PRIMARY KEY ("A_TABLE_STAT_HIST_KEY") + USING INDEX PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_KEY_SEQ.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_KEY_SEQ.sql new file mode 100644 index 0000000..4a2c345 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_KEY_SEQ.sql @@ -0,0 +1,6 @@ +-------------------------------------------------------- +-- DDL for Sequence A_TABLE_STAT_KEY_SEQ +-------------------------------------------------------- + + CREATE SEQUENCE "CT_MRDS"."A_TABLE_STAT_KEY_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 130 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL ; + GRANT SELECT ON "CT_MRDS"."A_TABLE_STAT_KEY_SEQ" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_UK1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_UK1.sql new file mode 100644 index 0000000..f420f53 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_UK1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_TABLE_STAT_UK1 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_TABLE_STAT_UK1" ON "CT_MRDS"."A_TABLE_STAT" ("A_SOURCE_FILE_CONFIG_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_UK1_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_UK1_1.sql new file mode 100644 index 0000000..f420f53 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TABLE_STAT_UK1_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_TABLE_STAT_UK1 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."A_TABLE_STAT_UK1" ON "CT_MRDS"."A_TABLE_STAT" ("A_SOURCE_FILE_CONFIG_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY.sql new file mode 100644 index 0000000..97901f8 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY.sql @@ -0,0 +1,30 @@ +-------------------------------------------------------- +-- DDL for Table A_TASK_HISTORY +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_TASK_HISTORY" + ( "A_TASK_HISTORY_KEY" NUMBER(38,0), + "A_WORKFLOW_HISTORY_KEY" NUMBER(38,0), + "TASK_RUN_ID" VARCHAR2(255 BYTE) COLLATE "USING_NLS_COMP", + "TASK_NAME" VARCHAR2(255 BYTE) COLLATE "USING_NLS_COMP", + "TASK_START" TIMESTAMP (6), + "TASK_END" TIMESTAMP (6), + "TASK_SUCCESSFUL" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "SERVICE_NAME" VARCHAR2(25 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY"."A_TASK_HISTORY_KEY" IS 'Surrogate key for logged subprocesses'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY"."A_WORKFLOW_HISTORY_KEY" IS 'Technical key to identify a load operation. Generated with Oracle sequence "CT_MRDS.SA_TASK_HISTORY_KEY_SEQ"'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY"."TASK_RUN_ID" IS 'Unique identifier for the task run'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY"."TASK_NAME" IS 'Mapping name of the logged subprocess'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY"."TASK_START" IS 'Start time of the subprocess'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY"."TASK_END" IS 'End time of the subprocess'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY"."TASK_SUCCESSFUL" IS 'Indicates that the subprocess completed successfully. Allowed values are ''RUNNING'', ''FAILED'', and ''SUCCESS''.'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY"."SERVICE_NAME" IS 'Database of reference'; + COMMENT ON TABLE "CT_MRDS"."A_TASK_HISTORY" IS 'This table logs subprocesses and their execution details.'; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_KEY_SEQ.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_KEY_SEQ.sql new file mode 100644 index 0000000..6080f77 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_KEY_SEQ.sql @@ -0,0 +1,6 @@ +-------------------------------------------------------- +-- DDL for Sequence A_TASK_HISTORY_KEY_SEQ +-------------------------------------------------------- + + CREATE SEQUENCE "CT_MRDS"."A_TASK_HISTORY_KEY_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1345716 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL ; + GRANT SELECT ON "CT_MRDS"."A_TASK_HISTORY_KEY_SEQ" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_SOURCE.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_SOURCE.sql new file mode 100644 index 0000000..b5d60d2 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_SOURCE.sql @@ -0,0 +1,26 @@ +-------------------------------------------------------- +-- DDL for Table A_TASK_HISTORY_SOURCE +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_TASK_HISTORY_SOURCE" + ( "A_TASK_HISTORY_SOURCE_KEY" NUMBER(38,0), + "A_TASK_HISTORY_KEY" NUMBER(38,0), + "A_WORKFLOW_HISTORY_SOURCE_KEY" NUMBER(38,0), + "SOURCE_NAME" VARCHAR2(255 BYTE) COLLATE "USING_NLS_COMP", + "ROW_COUNT" NUMBER(38,0), + "SERVICE_NAME" VARCHAR2(25 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_SOURCE"."A_TASK_HISTORY_SOURCE_KEY" IS 'Technical primary key'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_SOURCE"."A_TASK_HISTORY_KEY" IS 'Foreign key referencing the subprocess delivering to the target'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_SOURCE"."A_WORKFLOW_HISTORY_SOURCE_KEY" IS 'Technical key for the workflow history source'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_SOURCE"."SOURCE_NAME" IS 'Name of the source used in the load process'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_SOURCE"."ROW_COUNT" IS 'Number of rows read from the source during the load process'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_SOURCE"."SERVICE_NAME" IS 'Database of reference'; + COMMENT ON TABLE "CT_MRDS"."A_TASK_HISTORY_SOURCE" IS 'This table logs details of data sources used in load processes.'; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_SOURCE_KEY_SEQ.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_SOURCE_KEY_SEQ.sql new file mode 100644 index 0000000..5d2c18c --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_SOURCE_KEY_SEQ.sql @@ -0,0 +1,6 @@ +-------------------------------------------------------- +-- DDL for Sequence A_TASK_HISTORY_SOURCE_KEY_SEQ +-------------------------------------------------------- + + CREATE SEQUENCE "CT_MRDS"."A_TASK_HISTORY_SOURCE_KEY_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1102812 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL ; + GRANT SELECT ON "CT_MRDS"."A_TASK_HISTORY_SOURCE_KEY_SEQ" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_TARGET.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_TARGET.sql new file mode 100644 index 0000000..154dee6 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_TARGET.sql @@ -0,0 +1,28 @@ +-------------------------------------------------------- +-- DDL for Table A_TASK_HISTORY_TARGET +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_TASK_HISTORY_TARGET" + ( "A_TASK_HISTORY_TARGET_KEY" NUMBER(38,0), + "A_TASK_HISTORY_KEY" NUMBER(38,0), + "TARGET_NAME" VARCHAR2(255 BYTE) COLLATE "USING_NLS_COMP", + "ROW_COUNT_APPLIED" NUMBER(38,0), + "ROW_COUNT_REJECTED" NUMBER(38,0), + "LOAD_SUCCESSFUL" CHAR(1 CHAR) COLLATE "USING_NLS_COMP", + "SERVICE_NAME" VARCHAR2(25 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_TARGET"."A_TASK_HISTORY_TARGET_KEY" IS 'Technical primary key'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_TARGET"."A_TASK_HISTORY_KEY" IS 'Foreign key referencing the subprocess delivering to the target'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_TARGET"."TARGET_NAME" IS 'Name of the target where data is written during the load process'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_TARGET"."ROW_COUNT_APPLIED" IS 'Number of rows successfully applied (written to) the DWH target table during the load process'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_TARGET"."ROW_COUNT_REJECTED" IS 'Number of rows rejected (NOT written to) the DWH target table during the load process'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_TARGET"."LOAD_SUCCESSFUL" IS 'Indicates the success of the load process. Allowed values are ''RUNNING'', ''SUCCESS'', and ''FAILED''.'; + COMMENT ON COLUMN "CT_MRDS"."A_TASK_HISTORY_TARGET"."SERVICE_NAME" IS 'Database of reference'; + COMMENT ON TABLE "CT_MRDS"."A_TASK_HISTORY_TARGET" IS 'This table logs details of target data written during load processes.'; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_TARGET_KEY_SEQ.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_TARGET_KEY_SEQ.sql new file mode 100644 index 0000000..2d226c4 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_TASK_HISTORY_TARGET_KEY_SEQ.sql @@ -0,0 +1,6 @@ +-------------------------------------------------------- +-- DDL for Sequence A_TASK_HISTORY_TARGET_KEY_SEQ +-------------------------------------------------------- + + CREATE SEQUENCE "CT_MRDS"."A_TASK_HISTORY_TARGET_KEY_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1534235 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL ; + GRANT SELECT ON "CT_MRDS"."A_TASK_HISTORY_TARGET_KEY_SEQ" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY.sql new file mode 100644 index 0000000..eec75f9 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY.sql @@ -0,0 +1,320 @@ +-------------------------------------------------------- +-- DDL for Table A_WORKFLOW_HISTORY +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_WORKFLOW_HISTORY" + ( "A_WORKFLOW_HISTORY_KEY" NUMBER(38,0), + "ORCHESTRATION_RUN_ID" VARCHAR2(300 BYTE) COLLATE "USING_NLS_COMP", + "WORKFLOW_NAME" VARCHAR2(255 BYTE) COLLATE "USING_NLS_COMP", + "WORKFLOW_START" TIMESTAMP (6), + "WORKFLOW_END" TIMESTAMP (6), + "WORKFLOW_SUCCESSFUL" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "DBT_INVOCATION_ID" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "SERVICE_NAME" VARCHAR2(25 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; + + COMMENT ON COLUMN "CT_MRDS"."A_WORKFLOW_HISTORY"."A_WORKFLOW_HISTORY_KEY" IS 'Technical key to identify a load operation. Generated with Oracle sequence "CT_MRDS.SEQ_WORKFLOW_HISTORY"'; + COMMENT ON COLUMN "CT_MRDS"."A_WORKFLOW_HISTORY"."ORCHESTRATION_RUN_ID" IS 'Unique identifier for the orchestration run'; + COMMENT ON COLUMN "CT_MRDS"."A_WORKFLOW_HISTORY"."WORKFLOW_NAME" IS 'The name of the workflow'; + COMMENT ON COLUMN "CT_MRDS"."A_WORKFLOW_HISTORY"."WORKFLOW_START" IS 'Start time of the Airflow / Informatica workflow'; + COMMENT ON COLUMN "CT_MRDS"."A_WORKFLOW_HISTORY"."WORKFLOW_END" IS 'End time of the Airflow / Informatica workflow'; + COMMENT ON COLUMN "CT_MRDS"."A_WORKFLOW_HISTORY"."WORKFLOW_SUCCESSFUL" IS 'Overall status of the workflow. Allowed values are ''R'' (running), ''Y'' (yes), and ''N'' (no)'; + COMMENT ON COLUMN "CT_MRDS"."A_WORKFLOW_HISTORY"."DBT_INVOCATION_ID" IS 'Unique identifier for the DBT invocation'; + COMMENT ON COLUMN "CT_MRDS"."A_WORKFLOW_HISTORY"."SERVICE_NAME" IS 'Filter for the service: RAR, MOPDB, ODS'; + COMMENT ON TABLE "CT_MRDS"."A_WORKFLOW_HISTORY" IS 'This table logs details of workflow executions, including start and end times, and overall workflow status.'; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LED_MOPDB_RO"; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FXCD_REP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ROAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MONITOR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WKSP_CEVGA1CNRLJH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "KONRAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ET_TEMPLATES" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CPAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_ISIS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SHS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_FROM_C2DDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_EXS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AWSMIG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ELA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBMGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_SB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DUMMY_USR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MORA_RO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MRRNC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "REFERENCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR_DGM_MOSIL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOAMOF_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBSOFA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WSS_PUBLIC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ALESSIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBAIUSER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IDC_DATA_CHECK" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IU_ODB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPIDS_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BIDDER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_ADHOC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_TMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CHAT" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPEC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLLATERAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TECH_LOADER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_FOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_BMI_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD_INVESTIGATION" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_ARCHIVE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ECB_OEM_MONITOR_PDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_SBI_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DM_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MML_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TLTRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WLA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOA_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AP-RARTABLEAU" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FMCO_REPORTS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOPDB_LOADER_SOURCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_TECH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MFI" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADBSNMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RMAN$CATALOG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DS$ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS_HIST" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AP-WLA-MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_DWH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_WAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDBAPP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AP-ODSTABLEAU" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "GGADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADB_APP_STORE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DCAT_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SBI_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSMADJ" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MRR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_BKGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IW_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_EONIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FX" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CPAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_ISIS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SHS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_FROM_C2DDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_EXS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AWSMIG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ELA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBMGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_SB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DUMMY_USR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MORA_RO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MRRNC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "REFERENCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR_DGM_MOSIL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOAMOF_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBSOFA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WSS_PUBLIC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ET_TEMPLATES" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ALESSIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBAIUSER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IDC_DATA_CHECK" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IU_ODB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "KONRAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPIDS_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BIDDER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_ADHOC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_TMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CHAT" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPEC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLLATERAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TECH_LOADER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FXCD_REP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_FOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_BMI_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MRDS_LOADER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD_INVESTIGATION" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_ARCHIVE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ECB_OEM_MONITOR_PDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_SBI_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DM_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MML_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ROAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TLTRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WLA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WKSP_CEVGA1CNRLJH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOA_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FMCO_REPORTS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOPDB_LOADER_SOURCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_TECH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MFI" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADBSNMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RMAN$CATALOG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DS$ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS_HIST" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MONITOR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_DWH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_WAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDBAPP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "GGADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADB_APP_STORE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DCAT_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SBI_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSMADJ" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MRR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_BKGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IW_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_EONIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FX" WITH GRANT OPTION; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_1.sql new file mode 100644 index 0000000..f076756 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_1.sql @@ -0,0 +1,339 @@ +-------------------------------------------------------- +-- DDL for Trigger A_WORKFLOW_HISTORY +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."A_WORKFLOW_HISTORY" +AFTER INSERT OR UPDATE OF workflow_successful ON ct_mrds.a_workflow_history +REFERENCING NEW AS new OLD AS old +FOR EACH ROW +DECLARE + v_workflow_name VARCHAR2(128); + v_wla_id NUMBER; +BEGIN + IF :new.service_name = 'ODS' AND :new.workflow_name IN ( + 'w_ODS_LM_STANDING_FACILITIES', 'w_ODS_CSDB_DEBT', 'w_ODS_CSDB_DEBT_DAILY', 'w_ODS_CSDB_RATINGS_FULL', + 'w_ODS_TMS_LIMIT_ACCESS', 'w_ODS_TMS_PORTFOLIO_ACCESS', 'w_ODS_TMS_PORTFOLIO_TREE', + 'w_ODS_TMS_COLLATERAL_INVENTORY', 'w_ODS_TOP_FULLBIDARRAY_COMPILED', 'w_ODS_TOP_ANNOUNCEMENT', + 'w_ODS_TOP_ALLOTMENT_MODIFICATIONS', 'w_ODS_TOP_ALLOTMENT', 'w_ODS_CEPH_PRICING', 'w_ODS_C2D_MPEC' + ) THEN + IF :new.workflow_successful = 'Y' AND :new.workflow_successful <> NVL(:old.workflow_successful, 'N') THEN + CASE + WHEN :new.workflow_name = 'w_ODS_LM_STANDING_FACILITIES' THEN v_workflow_name := 'w_ODS_LM_STANDING_FACILITY'; + WHEN :new.workflow_name = 'w_ODS_TMS_LIMIT_ACCESS' THEN v_workflow_name := 'w_ODS_TMS_RAR_LIMITACCESS'; + WHEN :new.workflow_name = 'w_ODS_TMS_PORTFOLIO_ACCESS' THEN v_workflow_name := 'w_ODS_TMS_RAR_PORTFOLIOACCESS'; + WHEN :new.workflow_name = 'w_ODS_TMS_PORTFOLIO_TREE' THEN v_workflow_name := 'w_ODS_TMS_RAR_PORTFOLIOTREE'; + WHEN :new.workflow_name = 'w_ODS_TMS_COLLATERAL_INVENTORY' THEN v_workflow_name := 'w_ODS_TMS_RAR_RARCOLLATERALINVENTORY'; + WHEN :new.workflow_name = 'w_ODS_TOP_FULLBIDARRAY_COMPILED' THEN v_workflow_name := 'w_ODS_TOP_FULLBIDARRAY_COMPILED'; + WHEN :new.workflow_name = 'w_ODS_TOP_ANNOUNCEMENT' THEN v_workflow_name := 'w_ODS_TOP_ANNOUNCEMENT'; + WHEN :new.workflow_name = 'w_ODS_TOP_ALLOTMENT_MODIFICATIONS' THEN v_workflow_name := 'w_ODS_TOP_ALLOTMENT_MODIFICATIONS'; + WHEN :new.workflow_name = 'w_ODS_TOP_ALLOTMENT' THEN v_workflow_name := 'w_ODS_TOP_ALLOTMENT'; + WHEN :new.workflow_name = 'w_ODS_CEPH_PRICING' THEN v_workflow_name := 'w_ODS_CEPH_PRICING'; + WHEN :new.workflow_name = 'w_ODS_C2D_MPEC' THEN v_workflow_name := 'w_ODS_C2D_MPEC'; + ELSE + v_workflow_name := :new.workflow_name; + END CASE; + BEGIN + v_wla_id := TO_NUMBER(:new.orchestration_run_id); + EXCEPTION WHEN OTHERS THEN NULL; + END; + INSERT INTO ct_ods.a_load_history ( + a_etl_load_set_key, workflow_name, infa_run_id, load_start, load_end, exdi_appl_req_id, exdi_correlation_id, load_successful, wla_run_id, dq_flag + ) VALUES ( + :new.a_workflow_history_key, v_workflow_name, NULL, :new.workflow_start, :new.workflow_end, NULL, NULL, :new.workflow_successful, v_wla_id, 'F' + ); + END IF; + END IF; +END +; +/ +ALTER TRIGGER "CT_MRDS"."A_WORKFLOW_HISTORY" ENABLE; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LED_MOPDB_RO"; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FXCD_REP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ROAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MONITOR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WKSP_CEVGA1CNRLJH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "KONRAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ET_TEMPLATES" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CPAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_ISIS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SHS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_FROM_C2DDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_EXS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AWSMIG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ELA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBMGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_SB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DUMMY_USR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MORA_RO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MRRNC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "REFERENCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR_DGM_MOSIL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOAMOF_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBSOFA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WSS_PUBLIC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ALESSIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBAIUSER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IDC_DATA_CHECK" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IU_ODB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPIDS_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BIDDER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_ADHOC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_TMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CHAT" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPEC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLLATERAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TECH_LOADER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_FOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_BMI_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD_INVESTIGATION" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_ARCHIVE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ECB_OEM_MONITOR_PDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_SBI_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DM_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MML_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TLTRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WLA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOA_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AP-RARTABLEAU" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FMCO_REPORTS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOPDB_LOADER_SOURCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_TECH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MFI" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADBSNMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RMAN$CATALOG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DS$ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS_HIST" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AP-WLA-MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_DWH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_WAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDBAPP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AP-ODSTABLEAU" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "GGADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADB_APP_STORE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DCAT_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SBI_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSMADJ" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MRR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_BKGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IW_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_EONIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FX" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CPAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_ISIS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SHS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_FROM_C2DDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_EXS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AWSMIG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ELA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBMGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_SB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DUMMY_USR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MORA_RO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MRRNC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "REFERENCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR_DGM_MOSIL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOAMOF_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBSOFA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WSS_PUBLIC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ET_TEMPLATES" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ALESSIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBAIUSER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IDC_DATA_CHECK" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IU_ODB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "KONRAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPIDS_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BIDDER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_ADHOC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_TMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CHAT" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPEC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLLATERAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TECH_LOADER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FXCD_REP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_FOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_BMI_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MRDS_LOADER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD_INVESTIGATION" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_ARCHIVE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ECB_OEM_MONITOR_PDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_SBI_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DM_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MML_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ROAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TLTRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WLA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WKSP_CEVGA1CNRLJH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOA_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FMCO_REPORTS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOPDB_LOADER_SOURCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_TECH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MFI" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADBSNMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RMAN$CATALOG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DS$ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS_HIST" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MONITOR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_DWH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_WAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDBAPP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "GGADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADB_APP_STORE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DCAT_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SBI_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSMADJ" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MRR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_BKGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IW_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_EONIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FX" WITH GRANT OPTION; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_2.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_2.sql new file mode 100644 index 0000000..f076756 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_2.sql @@ -0,0 +1,339 @@ +-------------------------------------------------------- +-- DDL for Trigger A_WORKFLOW_HISTORY +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."A_WORKFLOW_HISTORY" +AFTER INSERT OR UPDATE OF workflow_successful ON ct_mrds.a_workflow_history +REFERENCING NEW AS new OLD AS old +FOR EACH ROW +DECLARE + v_workflow_name VARCHAR2(128); + v_wla_id NUMBER; +BEGIN + IF :new.service_name = 'ODS' AND :new.workflow_name IN ( + 'w_ODS_LM_STANDING_FACILITIES', 'w_ODS_CSDB_DEBT', 'w_ODS_CSDB_DEBT_DAILY', 'w_ODS_CSDB_RATINGS_FULL', + 'w_ODS_TMS_LIMIT_ACCESS', 'w_ODS_TMS_PORTFOLIO_ACCESS', 'w_ODS_TMS_PORTFOLIO_TREE', + 'w_ODS_TMS_COLLATERAL_INVENTORY', 'w_ODS_TOP_FULLBIDARRAY_COMPILED', 'w_ODS_TOP_ANNOUNCEMENT', + 'w_ODS_TOP_ALLOTMENT_MODIFICATIONS', 'w_ODS_TOP_ALLOTMENT', 'w_ODS_CEPH_PRICING', 'w_ODS_C2D_MPEC' + ) THEN + IF :new.workflow_successful = 'Y' AND :new.workflow_successful <> NVL(:old.workflow_successful, 'N') THEN + CASE + WHEN :new.workflow_name = 'w_ODS_LM_STANDING_FACILITIES' THEN v_workflow_name := 'w_ODS_LM_STANDING_FACILITY'; + WHEN :new.workflow_name = 'w_ODS_TMS_LIMIT_ACCESS' THEN v_workflow_name := 'w_ODS_TMS_RAR_LIMITACCESS'; + WHEN :new.workflow_name = 'w_ODS_TMS_PORTFOLIO_ACCESS' THEN v_workflow_name := 'w_ODS_TMS_RAR_PORTFOLIOACCESS'; + WHEN :new.workflow_name = 'w_ODS_TMS_PORTFOLIO_TREE' THEN v_workflow_name := 'w_ODS_TMS_RAR_PORTFOLIOTREE'; + WHEN :new.workflow_name = 'w_ODS_TMS_COLLATERAL_INVENTORY' THEN v_workflow_name := 'w_ODS_TMS_RAR_RARCOLLATERALINVENTORY'; + WHEN :new.workflow_name = 'w_ODS_TOP_FULLBIDARRAY_COMPILED' THEN v_workflow_name := 'w_ODS_TOP_FULLBIDARRAY_COMPILED'; + WHEN :new.workflow_name = 'w_ODS_TOP_ANNOUNCEMENT' THEN v_workflow_name := 'w_ODS_TOP_ANNOUNCEMENT'; + WHEN :new.workflow_name = 'w_ODS_TOP_ALLOTMENT_MODIFICATIONS' THEN v_workflow_name := 'w_ODS_TOP_ALLOTMENT_MODIFICATIONS'; + WHEN :new.workflow_name = 'w_ODS_TOP_ALLOTMENT' THEN v_workflow_name := 'w_ODS_TOP_ALLOTMENT'; + WHEN :new.workflow_name = 'w_ODS_CEPH_PRICING' THEN v_workflow_name := 'w_ODS_CEPH_PRICING'; + WHEN :new.workflow_name = 'w_ODS_C2D_MPEC' THEN v_workflow_name := 'w_ODS_C2D_MPEC'; + ELSE + v_workflow_name := :new.workflow_name; + END CASE; + BEGIN + v_wla_id := TO_NUMBER(:new.orchestration_run_id); + EXCEPTION WHEN OTHERS THEN NULL; + END; + INSERT INTO ct_ods.a_load_history ( + a_etl_load_set_key, workflow_name, infa_run_id, load_start, load_end, exdi_appl_req_id, exdi_correlation_id, load_successful, wla_run_id, dq_flag + ) VALUES ( + :new.a_workflow_history_key, v_workflow_name, NULL, :new.workflow_start, :new.workflow_end, NULL, NULL, :new.workflow_successful, v_wla_id, 'F' + ); + END IF; + END IF; +END +; +/ +ALTER TRIGGER "CT_MRDS"."A_WORKFLOW_HISTORY" ENABLE; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LED_MOPDB_RO"; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FXCD_REP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ROAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MONITOR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WKSP_CEVGA1CNRLJH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "KONRAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ET_TEMPLATES" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CPAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_ISIS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SHS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_FROM_C2DDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_EXS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AWSMIG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ELA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBMGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_SB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DUMMY_USR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MORA_RO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MRRNC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "REFERENCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR_DGM_MOSIL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOAMOF_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBSOFA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WSS_PUBLIC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ALESSIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBAIUSER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IDC_DATA_CHECK" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IU_ODB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPIDS_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BIDDER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_ADHOC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_TMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CHAT" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPEC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLLATERAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TECH_LOADER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_FOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_BMI_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD_INVESTIGATION" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_ARCHIVE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ECB_OEM_MONITOR_PDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_SBI_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DM_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MML_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TLTRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WLA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOA_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AP-RARTABLEAU" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FMCO_REPORTS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOPDB_LOADER_SOURCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_TECH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MFI" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADBSNMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RMAN$CATALOG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DS$ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS_HIST" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AP-WLA-MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_DWH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_WAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDBAPP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AP-ODSTABLEAU" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "GGADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADB_APP_STORE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DCAT_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SBI_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSMADJ" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MRR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_BKGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IW_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_EONIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FX" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CPAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_ISIS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_SHS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_FROM_C2DDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_EXS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "AWSMIG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ELA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBMGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_SB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DUMMY_USR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MORA_RO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MRRNC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "REFERENCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RAR_DGM_MOSIL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOAMOF_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBSOFA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WSS_PUBLIC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ET_TEMPLATES" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ALESSIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBAIUSER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IDC_DATA_CHECK" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IU_ODB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "KONRAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPIDS_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BIDDER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_ADHOC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_TMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "T2" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CHAT" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MPEC" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLLATERAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TECH_LOADER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FXCD_REP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_FOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_BMI_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MRDS_LOADER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TOP_HISTORY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RIAD_INVESTIGATION" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LEGACY_MFI_ARCHIVE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LBA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_RAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DBO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOS_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CT_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DW_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ECB_OEM_MONITOR_PDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_SBI_MOPDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DM_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MML_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ROAR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TLTRO" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WLA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "WKSP_CEVGA1CNRLJH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOA_APP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB_SHARED_USER" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FMCO_REPORTS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TEC_MOPDB_LOADER_SOURCE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_RAR_TECH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MFI" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "COLL_SHARED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADBSNMP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "RMAN$CATALOG" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DS$ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "TMS_HIST" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "PDBADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DGIS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MML_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOA_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BMI_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "FOS_LAB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_REF" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MONITOR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_LED" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_DALM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_FXCD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CEPH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_DWH" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY_WAL" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "MOPDBAPP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_RQSD" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SF_SDW" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "CORR_REF_MAIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "GGADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "ADB_APP_STORE" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "DCAT_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "SBI_ADMIN" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSMADJ" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LEGACY" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TOP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MRR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_MDP" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_BKGR" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_CSDB" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "IW_RTM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "BKP_ODS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_LM" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_TMS" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_EONIA" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_C2D" WITH GRANT OPTION; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY" TO "OU_FX" WITH GRANT OPTION; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_KEY_SEQ.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_KEY_SEQ.sql new file mode 100644 index 0000000..729a767 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_KEY_SEQ.sql @@ -0,0 +1,6 @@ +-------------------------------------------------------- +-- DDL for Sequence A_WORKFLOW_HISTORY_KEY_SEQ +-------------------------------------------------------- + + CREATE SEQUENCE "CT_MRDS"."A_WORKFLOW_HISTORY_KEY_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1521568 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL ; + GRANT SELECT ON "CT_MRDS"."A_WORKFLOW_HISTORY_KEY_SEQ" TO "MRDS_LOADER_ROLE"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY.sql new file mode 100644 index 0000000..9b3139f --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY.sql @@ -0,0 +1,16 @@ +-------------------------------------------------------- +-- DDL for Table A_WORKFLOW_HISTORY_PROPERTY +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."A_WORKFLOW_HISTORY_PROPERTY" + ( "A_WORKFLOW_HISTORY_KEY" NUMBER, + "SERVICE_NAME" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "PROPERTY" VARCHAR2(200 BYTE) COLLATE "USING_NLS_COMP", + "VALUE" VARCHAR2(4000 CHAR) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION IMMEDIATE + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY_IDX1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY_IDX1.sql new file mode 100644 index 0000000..b663afe --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY_IDX1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_WORKFLOW_HISTORY_PROPERTY_IDX1 +-------------------------------------------------------- + + CREATE INDEX "CT_MRDS"."A_WORKFLOW_HISTORY_PROPERTY_IDX1" ON "CT_MRDS"."A_WORKFLOW_HISTORY_PROPERTY" ("A_WORKFLOW_HISTORY_KEY", "SERVICE_NAME") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY_IDX1_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY_IDX1_1.sql new file mode 100644 index 0000000..b663afe --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/A_WORKFLOW_HISTORY_PROPERTY_IDX1_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index A_WORKFLOW_HISTORY_PROPERTY_IDX1 +-------------------------------------------------------- + + CREATE INDEX "CT_MRDS"."A_WORKFLOW_HISTORY_PROPERTY_IDX1" ON "CT_MRDS"."A_WORKFLOW_HISTORY_PROPERTY" ("A_WORKFLOW_HISTORY_KEY", "SERVICE_NAME") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/CHECK_LINK.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/CHECK_LINK.sql new file mode 100644 index 0000000..2cf747a --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/CHECK_LINK.sql @@ -0,0 +1,22 @@ +-------------------------------------------------------- +-- DDL for Function CHECK_LINK +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE FUNCTION "PDBADMIN"."CHECK_LINK" ( p_link varchar2 ) +RETURN VARCHAR +AUTHID DEFINER IS +v_checked VARCHAR2(200); +aaa VARCHAR2(200); +BEGIN + aaa:='SELECT * INTO v_checked FROM sys.dual@'||p_link ; + execute immediate aaa; + dbms_output.put_line ('Test Outcome: '|| v_checked) ; + + if v_checked ='X' + then return 'OK'; + else return 'KO'; + END IF; + +END CHECK_LINK ; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/CT_MRDS.7z b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/CT_MRDS.7z new file mode 100644 index 0000000000000000000000000000000000000000..cb57c42a2b086adaab8d1edaa7402ead74928cd0 GIT binary patch literal 68522 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

0Mz!k|IrkfNp_ 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 Q000c9E(!s9!%G?f0HX 'CT_MRDS', + * pTableName => 'MY_TABLE', + * pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK', + * pBucketArea => 'DATA', + * pFolderName => 'csv_exports', + * pFileName => 'my_export.csv', -- Optional + * pTemplateTableName => 'CT_ET_TEMPLATES.MY_TEMPLATE', -- Optional + * pMaxFileSize => 104857600, -- Optional, default 100MB + * pRegisterExport => TRUE -- Optional, default FALSE + * ); + * end; + **/ + PROCEDURE EXPORT_TABLE_DATA ( + pSchemaName IN VARCHAR2, + pTableName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pBucketArea IN VARCHAR2, + pFolderName IN VARCHAR2, + pFileName IN VARCHAR2 default NULL, + pTemplateTableName IN VARCHAR2 default NULL, + pMaxFileSize IN NUMBER default 104857600, + pRegisterExport IN BOOLEAN default FALSE, + pProcessName IN VARCHAR2 default 'DATA_EXPORTER', + pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName + ); + + + + /** + * @name EXPORT_TABLE_DATA_BY_DATE + * @desc Wrapper procedure for DBMS_CLOUD.EXPORT_DATA. + * Exports data into PARQUET files on OCI infrustructure. + * Each YEAR_MONTH pair goes to seperate file (implicit partitioning). + * Allows specifying custom column list or uses T.* if pColumnList is NULL. + * Validates that all columns in pColumnList exist in the target table. + * Automatically adds 'T.' prefix to column names in pColumnList. + * Supports parallel partition processing via pParallelDegree parameter (default 1, range 1-16). + * pBucketArea parameter accepts: 'INBOX', 'ODS', 'DATA', 'ARCHIVE' + * @example + * begin + * DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE( + * pSchemaName => 'CT_MRDS', + * pTableName => 'MY_TABLE', + * pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK', + * pBucketArea => 'DATA', + * pFolderName => 'parquet_exports', + * pColumnList => 'COLUMN1, COLUMN2, COLUMN3', -- Optional + * pMinDate => DATE '2024-01-01', + * pMaxDate => SYSDATE, + * pParallelDegree => 8 -- Optional, default 1, range 1-16 + * ); + * end; + **/ + PROCEDURE EXPORT_TABLE_DATA_BY_DATE ( + pSchemaName IN VARCHAR2, + pTableName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pBucketArea IN VARCHAR2, + pFolderName IN VARCHAR2, + pColumnList IN VARCHAR2 default NULL, + pMinDate IN DATE default DATE '1900-01-01', + pMaxDate IN DATE default SYSDATE, + pParallelDegree IN NUMBER default 1, + pTemplateTableName IN VARCHAR2 default NULL, + pJobClass IN VARCHAR2 default NULL, + pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName + ); + + + + /** + * @name EXPORT_TABLE_DATA_TO_CSV_BY_DATE + * @desc Exports data to separate CSV files partitioned by year and month. + * Creates one CSV file for each year/month combination found in the data. + * Uses the same date filtering mechanism with CT_ODS.A_LOAD_HISTORY as EXPORT_TABLE_DATA_BY_DATE, + * but exports to CSV format instead of Parquet. + * Supports parallel partition processing via pParallelDegree parameter (1-16). + * File naming pattern: {pFileName}_YYYYMM.csv or {TABLENAME}_YYYYMM.csv (if pFileName is NULL) + * When pRegisterExport=TRUE, successfully exported files are registered in: + * - CT_MRDS.A_SOURCE_FILE_RECEIVED (tracks file location, size, checksum, and metadata) + * @param pProcessName - Process name stored in PROCESS_NAME column (default 'DATA_EXPORTER') + * @example + * begin + * -- With custom filename + * DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE( + * pSchemaName => 'CT_MRDS', + * pTableName => 'MY_TABLE', + * pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK', + * pBucketArea => 'DATA', + * pFolderName => 'exports', + * pFileName => 'my_export.csv', + * pMinDate => DATE '2024-01-01', + * pMaxDate => SYSDATE, + * pParallelDegree => 8, -- Optional, default 1, range 1-16 + * pRegisterExport => TRUE -- Optional, default FALSE, registers to A_SOURCE_FILE_RECEIVED + * ); + * + * -- With auto-generated filename (based on table name only) + * DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE( + * pSchemaName => 'OU_TOP', + * pTableName => 'AGGREGATED_ALLOTMENT', + * pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK', + * pBucketArea => 'ARCHIVE', + * pFolderName => 'exports', + * pMinDate => DATE '2025-09-01', + * pMaxDate => DATE '2025-09-17', + * pRegisterExport => TRUE -- Registers each export to A_SOURCE_FILE_RECEIVED table + * ); + * -- This will create files like: AGGREGATED_ALLOTMENT_202509.csv, etc. + * pBucketArea parameter accepts: 'INBOX', 'ODS', 'DATA', 'ARCHIVE' + * end; + **/ + PROCEDURE EXPORT_TABLE_DATA_TO_CSV_BY_DATE ( + pSchemaName IN VARCHAR2, + pTableName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pBucketArea IN VARCHAR2, + pFolderName IN VARCHAR2, + pFileName IN VARCHAR2 DEFAULT NULL, + pColumnList IN VARCHAR2 default NULL, + pMinDate IN DATE default DATE '1900-01-01', + pMaxDate IN DATE default SYSDATE, + pParallelDegree IN NUMBER default 1, + pTemplateTableName IN VARCHAR2 default NULL, + pMaxFileSize IN NUMBER default 104857600, + pRegisterExport IN BOOLEAN default FALSE, + pProcessName IN VARCHAR2 default 'DATA_EXPORTER', + pJobClass IN VARCHAR2 default NULL, + pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName + ); + + --------------------------------------------------------------------------------------------------------------------------- + -- VERSION MANAGEMENT FUNCTIONS + --------------------------------------------------------------------------------------------------------------------------- + + /** + * Returns the current package version number + * return: Version string in format X.Y.Z (e.g., '2.1.0') + **/ + FUNCTION GET_VERSION RETURN VARCHAR2; + + /** + * Returns comprehensive build information including version, date, and author + * return: Formatted string with complete build details + **/ + FUNCTION GET_BUILD_INFO RETURN VARCHAR2; + + /** + * Returns the version history with recent changes + * return: Multi-line string with version history + **/ + FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2; + +END; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DATA_EXPORTER_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DATA_EXPORTER_1.sql new file mode 100644 index 0000000..3d54f23 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DATA_EXPORTER_1.sql @@ -0,0 +1,1786 @@ +-------------------------------------------------------- +-- DDL for Package Body DATA_EXPORTER +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE PACKAGE BODY "CT_MRDS"."DATA_EXPORTER" +AS + + ---------------------------------------------------------------------------------------------------- + -- PRIVATE HELPER FUNCTIONS (USED BY MULTIPLE PROCEDURES) + ---------------------------------------------------------------------------------------------------- + + /** + * Sanitizes filename by replacing disallowed characters with underscores + **/ + FUNCTION sanitizeFilename(pFilename IN VARCHAR2) RETURN VARCHAR2 IS + vFilename VARCHAR2(1000); + BEGIN + vFilename := REGEXP_REPLACE(pFilename, '[^a-zA-Z0-9._-]', '_'); + RETURN vFilename; + END sanitizeFilename; + + ---------------------------------------------------------------------------------------------------- + + /** + * Deletes ALL files matching specific file pattern before retry export + * Critical for preventing data duplication when DBMS_CLOUD.EXPORT_DATA fails mid-process + * + * Problem: Export fails after creating partial file(s), retry creates new _2, _3 suffixed files + * Solution: Delete ALL files matching the base filename pattern before retry + * + * Pattern matching strategy: + * - Parquet: folder/PARTITION_YEAR=2024/PARTITION_MONTH=11/*.parquet (folder-level safe - each chunk has own partition folder) + * - CSV: folder/TABLENAME_202411*.csv (file-level pattern - multiple chunks share same folder!) + * + * CRITICAL for parallel processing: + * - Parquet chunks are isolated by partition folder structure (safe to delete folder/*) + * - CSV chunks share flat folder structure - MUST use file-specific pattern (TABLENAME_YYYYMM*) + * to avoid deleting files from other parallel chunks in same folder + **/ + PROCEDURE DELETE_FAILED_EXPORT_FILE( + pFileUri IN VARCHAR2, + pCredentialName IN VARCHAR2, + pParameters IN VARCHAR2 + ) IS + vBucketUri VARCHAR2(4000); + vFolderPath VARCHAR2(4000); + vFileName VARCHAR2(1000); + vFileNamePattern VARCHAR2(1000); + vSlashPos NUMBER; + vDotPos NUMBER; + vFilesDeleted NUMBER := 0; + BEGIN + -- Extract components from URI + -- Example Parquet: https://.../bucket/folder/PARTITION_YEAR=2024/PARTITION_MONTH=11/202411.parquet + -- Example CSV: https://.../bucket/folder/TABLENAME_202411.csv + + -- Find last slash before filename + vSlashPos := INSTR(pFileUri, '/', -1); + + IF vSlashPos > 0 THEN + -- Extract filename from URI (after last slash) + vFileName := SUBSTR(pFileUri, vSlashPos + 1); + + -- Extract folder path (before last slash) + vFolderPath := SUBSTR(pFileUri, 1, vSlashPos - 1); + + -- Find bucket URI (protocol + namespace + bucket name) + -- Bucket URI ends after /o/ in OCI Object Storage URLs + vBucketUri := SUBSTR(pFileUri, 1, INSTR(pFileUri, '/o/') + 2); + + -- Extract relative folder path (after bucket) + vFolderPath := SUBSTR(vFolderPath, LENGTH(vBucketUri) + 1); + + -- Create file pattern by removing extension + -- Oracle adds suffixes BEFORE extension: file.csv -> file_1_timestamp.csv + -- Pattern: file* matches file_1_timestamp.csv, file_2_timestamp.csv + vDotPos := INSTR(vFileName, '.', -1); + IF vDotPos > 0 THEN + vFileNamePattern := SUBSTR(vFileName, 1, vDotPos - 1) || '%'; + ELSE + vFileNamePattern := vFileName || '%'; + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('Cleanup before retry - Pattern: ' || vFolderPath || '/' || vFileNamePattern, 'DEBUG', pParameters); + + -- List and delete ALL files matching pattern + -- CRITICAL: Uses file-specific pattern for CSV chunk isolation in shared folder + FOR rec IN ( + SELECT object_name + FROM TABLE(DBMS_CLOUD.LIST_OBJECTS( + credential_name => pCredentialName, + location_uri => vBucketUri + )) + WHERE object_name LIKE vFolderPath || '/' || vFileNamePattern + ) LOOP + BEGIN + DBMS_CLOUD.DELETE_OBJECT( + credential_name => pCredentialName, + object_uri => vBucketUri || rec.object_name + ); + + vFilesDeleted := vFilesDeleted + 1; + ENV_MANAGER.LOG_PROCESS_EVENT('Deleted partial file ' || vFilesDeleted || ': ' || rec.object_name, 'DEBUG', pParameters); + EXCEPTION + WHEN OTHERS THEN + -- Log but continue - don't fail entire cleanup + ENV_MANAGER.LOG_PROCESS_EVENT('Warning: Could not delete ' || rec.object_name || ': ' || SQLERRM, 'WARNING', pParameters); + END; + END LOOP; + + IF vFilesDeleted > 0 THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Cleanup completed: Deleted ' || vFilesDeleted || ' partial file(s) from previous failed export', 'INFO', pParameters); + ELSE + ENV_MANAGER.LOG_PROCESS_EVENT('No existing files to clean up (pattern match: ' || vFileNamePattern || ')', 'DEBUG', pParameters); + END IF; + ELSE + ENV_MANAGER.LOG_PROCESS_EVENT('Warning: Cannot parse file URI for cleanup: ' || pFileUri, 'WARNING', pParameters); + END IF; + EXCEPTION + WHEN OTHERS THEN + -- Don't fail export if cleanup fails - log and continue + ENV_MANAGER.LOG_PROCESS_EVENT('Warning: Cleanup failed (will retry export anyway): ' || SQLERRM, 'WARNING', pParameters); + END DELETE_FAILED_EXPORT_FILE; + + ---------------------------------------------------------------------------------------------------- + + /** + * Builds query with TO_CHAR for date/timestamp columns using per-column formats + * Retrieves format for each date column from FILE_MANAGER.GET_DATE_FORMAT + **/ + FUNCTION buildQueryWithDateFormats( + pColumnList IN VARCHAR2, + pTableName IN VARCHAR2, + pSchemaName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pTemplateTableName IN VARCHAR2 + ) RETURN VARCHAR2 IS + vResult VARCHAR2(32767); + vColumns VARCHAR2(32767); + vPos PLS_INTEGER; + vNextPos PLS_INTEGER; + vCurrentCol VARCHAR2(128); + vAllCols VARCHAR2(32767); + vDataType VARCHAR2(30); + vDateFormat VARCHAR2(200); + vTemplateSchema VARCHAR2(128); + vTemplateTable VARCHAR2(128); + vColExists NUMBER; + BEGIN + -- Build column list if not provided + IF pColumnList IS NULL THEN + -- Use template table for column order when provided + -- Template defines which columns to export and in what order + IF pTemplateTableName IS NOT NULL THEN + -- Parse template table name (SCHEMA.TABLE or just TABLE) + IF INSTR(pTemplateTableName, '.') > 0 THEN + vTemplateSchema := SUBSTR(pTemplateTableName, 1, INSTR(pTemplateTableName, '.') - 1); + vTemplateTable := SUBSTR(pTemplateTableName, INSTR(pTemplateTableName, '.') + 1); + ELSE + vTemplateSchema := pSchemaName; + vTemplateTable := pTemplateTableName; + END IF; + + -- Get columns from TEMPLATE table in template column order + -- Template defines target CSV structure (column order and which columns to include) + SELECT LISTAGG(column_name, ', ') WITHIN GROUP (ORDER BY column_id) + INTO vAllCols + FROM all_tab_columns + WHERE table_name = vTemplateTable + AND owner = vTemplateSchema; + ELSE + -- Get columns from source table when no template + SELECT LISTAGG(column_name, ', ') WITHIN GROUP (ORDER BY column_id) + INTO vAllCols + FROM all_tab_columns + WHERE table_name = pTableName + AND owner = pSchemaName; + END IF; + ELSE + vAllCols := pColumnList; + END IF; + + -- Process each column + vColumns := UPPER(REPLACE(vAllCols, ' ', '')); + vPos := 1; + vResult := ''; + + WHILE vPos <= LENGTH(vColumns) LOOP + vNextPos := INSTR(vColumns, ',', vPos); + IF vNextPos = 0 THEN + vNextPos := LENGTH(vColumns) + 1; + END IF; + + vCurrentCol := SUBSTR(vColumns, vPos, vNextPos - vPos); + + -- When using template table, check if column exists in SOURCE table + -- Template defines target structure, source provides data + -- Skip template columns that don't exist in source (except A_WORKFLOW_HISTORY_KEY) + IF pTemplateTableName IS NOT NULL THEN + -- Check if template column exists in SOURCE table + SELECT COUNT(*) INTO vColExists + FROM all_tab_columns + WHERE table_name = pTableName + AND column_name = vCurrentCol + AND owner = pSchemaName; + + -- Skip columns that don't exist in source table + -- Exception: A_WORKFLOW_HISTORY_KEY is virtual (mapped from pKeyColumnName) + IF vColExists = 0 AND UPPER(vCurrentCol) != 'A_WORKFLOW_HISTORY_KEY' THEN + vPos := vNextPos + 1; + CONTINUE; + END IF; + END IF; + + -- Get column data type from appropriate table (template or source) + IF pTemplateTableName IS NOT NULL THEN + -- Get data type from template table + SELECT data_type INTO vDataType + FROM all_tab_columns + WHERE table_name = vTemplateTable + AND column_name = vCurrentCol + AND owner = vTemplateSchema; + ELSE + -- Get data type from source table + SELECT data_type INTO vDataType + FROM all_tab_columns + WHERE table_name = pTableName + AND column_name = vCurrentCol + AND owner = pSchemaName; + END IF; + + -- Handle key column alias (template table has A_WORKFLOW_HISTORY_KEY, source table has pKeyColumnName) + IF UPPER(vCurrentCol) = 'A_WORKFLOW_HISTORY_KEY' THEN + vResult := vResult || CASE WHEN vResult IS NOT NULL THEN ', ' ELSE '' END || + 'T.' || pKeyColumnName || ' AS A_WORKFLOW_HISTORY_KEY'; + + -- Convert DATE/TIMESTAMP columns to CHAR with specific format + ELSIF vDataType IN ('DATE', 'TIMESTAMP', 'TIMESTAMP WITH TIME ZONE', 'TIMESTAMP WITH LOCAL TIME ZONE') THEN + IF pTemplateTableName IS NOT NULL THEN + vDateFormat := CT_MRDS.FILE_MANAGER.GET_DATE_FORMAT( + pTemplateTableName => pTemplateTableName, + pColumnName => vCurrentCol + ); + ELSE + vDateFormat := ENV_MANAGER.gvDefaultDateFormat; + END IF; + vResult := vResult || CASE WHEN vResult IS NOT NULL THEN ', ' ELSE '' END || + 'TO_CHAR(T.' || vCurrentCol || ', ''' || vDateFormat || ''') AS ' || vCurrentCol; + + -- Other columns as-is with T. prefix + ELSE + vResult := vResult || CASE WHEN vResult IS NOT NULL THEN ', ' ELSE '' END || + 'T.' || vCurrentCol; + END IF; + + vPos := vNextPos + 1; + END LOOP; + + RETURN vResult; + END buildQueryWithDateFormats; + + ---------------------------------------------------------------------------------------------------- + + -- Internal shared function to process column list with T. prefix and key column mapping + FUNCTION processColumnList(pColumnList IN VARCHAR2, pTableName IN VARCHAR2, pSchemaName IN VARCHAR2, pKeyColumnName IN VARCHAR2) RETURN VARCHAR2 IS + vResult VARCHAR2(32767); + vColumns VARCHAR2(32767); + vPos PLS_INTEGER; + vNextPos PLS_INTEGER; + vCurrentCol VARCHAR2(128); + vAllCols VARCHAR2(32767); + BEGIN + IF pColumnList IS NULL THEN + -- Build list of all columns + SELECT LISTAGG(column_name, ', ') WITHIN GROUP (ORDER BY column_id) + INTO vAllCols + FROM all_tab_columns + WHERE table_name = pTableName + AND owner = pSchemaName; + + -- Add T. prefix to all columns + vResult := 'T.' || REPLACE(vAllCols, ', ', ', T.'); + + -- Replace key column with aliased version (e.g., T.A_ETL_LOAD_SET_KEY_FK AS A_WORKFLOW_HISTORY_KEY) + vResult := REPLACE(vResult, 'T.' || pKeyColumnName, 'T.' || pKeyColumnName || ' AS A_WORKFLOW_HISTORY_KEY'); + + RETURN vResult; + END IF; + + -- Remove extra spaces and convert to uppercase + vColumns := UPPER(REPLACE(pColumnList, ' ', '')); + vPos := 1; + vResult := ''; + + -- Parse comma-separated column list and add T. prefix + WHILE vPos <= LENGTH(vColumns) LOOP + vNextPos := INSTR(vColumns, ',', vPos); + IF vNextPos = 0 THEN + vNextPos := LENGTH(vColumns) + 1; + END IF; + + vCurrentCol := SUBSTR(vColumns, vPos, vNextPos - vPos); + + -- Check if this is the key column (e.g., A_ETL_LOAD_SET_KEY_FK) and add alias + IF UPPER(vCurrentCol) = UPPER(pKeyColumnName) THEN + vCurrentCol := 'T.' || pKeyColumnName || ' AS A_WORKFLOW_HISTORY_KEY'; + ELSE + -- Add T. prefix if not already present + IF INSTR(vCurrentCol, '.') = 0 THEN + vCurrentCol := 'T.' || vCurrentCol; + END IF; + END IF; + + -- Add to result with comma separator + IF vResult IS NOT NULL THEN + vResult := vResult || ', '; + END IF; + vResult := vResult || vCurrentCol; + + vPos := vNextPos + 1; + END LOOP; + + RETURN vResult; + END processColumnList; + + ---------------------------------------------------------------------------------------------------- + + /** + * Validates table existence, key column existence, and column list + **/ + PROCEDURE VALIDATE_TABLE_AND_COLUMNS ( + pSchemaName IN VARCHAR2, + pTableName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pColumnList IN VARCHAR2, + pParameters IN VARCHAR2 + ) IS + vCount INTEGER; + vColumns VARCHAR2(32767); + vPos PLS_INTEGER; + vNextPos PLS_INTEGER; + vCurrentCol VARCHAR2(128); + BEGIN + -- Check if table exists + SELECT COUNT(*) INTO vCount + FROM all_tables + WHERE table_name = pTableName + AND owner = pSchemaName; + + IF vCount = 0 THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_TABLE_NOT_EXISTS, ENV_MANAGER.MSG_TABLE_NOT_EXISTS); + END IF; + + -- Check if key column exists + SELECT COUNT(*) INTO vCount + FROM all_tab_columns + WHERE table_name = pTableName + AND column_name = pKeyColumnName + AND owner = pSchemaName; + + IF vCount = 0 THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_COLUMN_NOT_EXISTS, ENV_MANAGER.MSG_COLUMN_NOT_EXISTS); + END IF; + + -- Validate pColumnList - check if all column names exist in the table + IF pColumnList IS NOT NULL THEN + vColumns := UPPER(REPLACE(pColumnList, ' ', '')); + vPos := 1; + + WHILE vPos <= LENGTH(vColumns) LOOP + vNextPos := INSTR(vColumns, ',', vPos); + IF vNextPos = 0 THEN + vNextPos := LENGTH(vColumns) + 1; + END IF; + + vCurrentCol := SUBSTR(vColumns, vPos, vNextPos - vPos); + + -- Remove table alias prefix if present + IF INSTR(vCurrentCol, '.') > 0 THEN + vCurrentCol := SUBSTR(vCurrentCol, INSTR(vCurrentCol, '.') + 1); + END IF; + + -- Check if column exists + SELECT COUNT(*) INTO vCount + FROM all_tab_columns + WHERE table_name = pTableName + AND column_name = vCurrentCol + AND owner = pSchemaName; + + IF vCount = 0 THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_COLUMN_NOT_EXISTS, ENV_MANAGER.MSG_COLUMN_NOT_EXISTS); + END IF; + + vPos := vNextPos + 1; + END LOOP; + END IF; + END VALIDATE_TABLE_AND_COLUMNS; + + ---------------------------------------------------------------------------------------------------- + + /** + * Retrieves list of year/month partitions based on date range + **/ + FUNCTION GET_PARTITIONS ( + pSchemaName IN VARCHAR2, + pTableName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pMinDate IN DATE, + pMaxDate IN DATE, + pParameters IN VARCHAR2 + ) RETURN partition_tab IS + vSql VARCHAR2(32000); + vPartitions partition_tab; + vKeyValuesYear DBMS_SQL.VARCHAR2_TABLE; + vKeyValuesMonth DBMS_SQL.VARCHAR2_TABLE; + vFullTableName VARCHAR2(200); + BEGIN + -- Build fully qualified table name if not already qualified + IF INSTR(pTableName, '.') > 0 THEN + vFullTableName := pTableName; -- Already fully qualified + ELSE + vFullTableName := pSchemaName || '.' || pTableName; + END IF; + + vSql := 'SELECT DISTINCT TO_CHAR(L.LOAD_START,''YYYY'') AS YR, TO_CHAR(L.LOAD_START,''MM'') AS MN + FROM ' || vFullTableName || ' T, CT_ODS.A_LOAD_HISTORY L + WHERE T.' || pKeyColumnName || ' = L.A_ETL_LOAD_SET_KEY + AND L.LOAD_START >= :pMinDate + AND L.LOAD_START < :pMaxDate + ORDER BY YR, MN'; + + ENV_MANAGER.LOG_PROCESS_EVENT('Executing date range query: ' || vSql, 'DEBUG', pParameters); + EXECUTE IMMEDIATE vSql BULK COLLECT INTO vKeyValuesYear, vKeyValuesMonth USING pMinDate, pMaxDate; + + ENV_MANAGER.LOG_PROCESS_EVENT('Found ' || vKeyValuesYear.COUNT || ' year/month combinations to export', 'DEBUG', pParameters); + + -- Convert to partition_tab + vPartitions := partition_tab(); + vPartitions.EXTEND(vKeyValuesYear.COUNT); + FOR i IN 1 .. vKeyValuesYear.COUNT LOOP + vPartitions(i).year := vKeyValuesYear(i); + vPartitions(i).month := vKeyValuesMonth(i); + END LOOP; + + RETURN vPartitions; + END GET_PARTITIONS; + + ---------------------------------------------------------------------------------------------------- + + /** + * Exports single partition (year/month) to specified format (PARQUET or CSV) + * This is the core worker procedure that will be used for parallel processing in v2.3.0 + **/ + PROCEDURE EXPORT_SINGLE_PARTITION ( + pSchemaName IN VARCHAR2, + pTableName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pYear IN VARCHAR2, + pMonth IN VARCHAR2, + pBucketUri IN VARCHAR2, + pFolderName IN VARCHAR2, + pProcessedColumns IN VARCHAR2, + pMinDate IN DATE, + pMaxDate IN DATE, + pCredentialName IN VARCHAR2, + pFormat IN VARCHAR2 DEFAULT 'PARQUET', + pFileBaseName IN VARCHAR2 DEFAULT NULL, + pMaxFileSize IN NUMBER DEFAULT 104857600, + pParameters IN VARCHAR2 + ) IS + vQuery VARCHAR2(32767); + vUri VARCHAR2(4000); + vFileName VARCHAR2(1000); + vFullTableName VARCHAR2(200); + BEGIN + -- Build fully qualified table name if not already qualified + IF INSTR(pTableName, '.') > 0 THEN + vFullTableName := pTableName; -- Already fully qualified + ELSE + vFullTableName := pSchemaName || '.' || pTableName; + END IF; + + -- Construct the query to extract data for the current year/month + vQuery := 'SELECT ' || pProcessedColumns || ' + FROM ' || vFullTableName || ' T, CT_ODS.A_LOAD_HISTORY L + WHERE T.' || pKeyColumnName || ' = L.A_ETL_LOAD_SET_KEY + AND TO_CHAR(L.LOAD_START,''YYYY'') = ' || CHR(39) || pYear || CHR(39) || ' + AND TO_CHAR(L.LOAD_START,''MM'') = ' || CHR(39) || pMonth || CHR(39) || ' + AND L.LOAD_START >= TO_DATE(' || CHR(39) || TO_CHAR(pMinDate, 'YYYY-MM-DD HH24:MI:SS') || CHR(39) || ', ''YYYY-MM-DD HH24:MI:SS'') + AND L.LOAD_START < TO_DATE(' || CHR(39) || TO_CHAR(pMaxDate, 'YYYY-MM-DD HH24:MI:SS') || CHR(39) || ', ''YYYY-MM-DD HH24:MI:SS'')'; + + ENV_MANAGER.LOG_PROCESS_EVENT('Processing Year/Month: ' || pYear || '/' || pMonth || ' (Format: '||pFormat||')', 'DEBUG', pParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Export query: ' || vQuery, 'DEBUG', pParameters); + -- Construct the URI based on format + IF pFormat = 'PARQUET' THEN + -- Parquet: Use Hive-style partitioning + -- Note: maxfilesize is NOT supported for Parquet format (Oracle limitation) + vUri := pBucketUri || + CASE WHEN pFolderName IS NOT NULL THEN pFolderName || '/' ELSE '' END || + 'PARTITION_YEAR=' || sanitizeFilename(pYear) || '/' || + 'PARTITION_MONTH=' || sanitizeFilename(pMonth) || '/' || + sanitizeFilename(pYear) || sanitizeFilename(pMonth) || '.parquet'; + + + ENV_MANAGER.LOG_PROCESS_EVENT('Parquet export URI: ' || vUri, 'DEBUG', pParameters); + + -- Delete potentially corrupted file from previous failed attempt + -- This prevents Oracle from creating _1 suffixed files on retry + DELETE_FAILED_EXPORT_FILE(vUri, pCredentialName, pParameters); + + DBMS_CLOUD.EXPORT_DATA( + credential_name => pCredentialName, + file_uri_list => vUri, + query => vQuery, + format => json_object('type' VALUE 'parquet') + ); + ELSIF pFormat = 'CSV' THEN + -- CSV: Flat file structure with year/month in filename + vFileName := NVL(pFileBaseName, UPPER(pTableName)) || '_' || pYear || pMonth || '.csv'; + vUri := pBucketUri || + CASE WHEN pFolderName IS NOT NULL THEN pFolderName || '/' ELSE '' END || + sanitizeFilename(vFileName); + + ENV_MANAGER.LOG_PROCESS_EVENT('CSV export URI: ' || vUri, 'DEBUG', pParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('CSV maxfilesize: ' || pMaxFileSize || ' bytes (' || ROUND(pMaxFileSize/1048576, 2) || ' MB)', 'DEBUG', pParameters); + + -- Delete potentially corrupted file from previous failed attempt + -- This prevents Oracle from creating _1 suffixed files on retry + DELETE_FAILED_EXPORT_FILE(vUri, pCredentialName, pParameters); + + -- Use json_object() for CSV export with maxfilesize in bytes (Oracle requirement) + -- Oracle maxfilesize: min 10MB (10485760), max 1GB (1073741824), default 10MB + -- NOTE: maxfilesize must be NUMBER (bytes), not string like '1000M' + -- Using 100MB (104857600) to avoid PGA memory issues with large files + DBMS_CLOUD.EXPORT_DATA( + credential_name => pCredentialName, + file_uri_list => vUri, + query => vQuery, + format => json_object( + 'type' VALUE 'CSV', + 'header' VALUE true, + 'quote' VALUE CHR(34), + 'delimiter' VALUE ',', + 'escape' VALUE true, + 'recorddelimiter' VALUE CHR(13)||CHR(10), -- CRLF dla Windows + 'maxfilesize' VALUE pMaxFileSize -- Dynamic maxfilesize in bytes (e.g., 104857600 = 100MB) + ) + ); + ELSE + RAISE_APPLICATION_ERROR(-20001, 'Unsupported format: ' || pFormat || '. Use PARQUET or CSV.'); + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('Export completed successfully for ' || pYear || '/' || pMonth, 'DEBUG', pParameters); + END EXPORT_SINGLE_PARTITION; + + ---------------------------------------------------------------------------------------------------- + + /** + * Callback procedure for DBMS_PARALLEL_EXECUTE + * Processes single partition (year/month) chunk in parallel task + * Called by DBMS_PARALLEL_EXECUTE framework for each chunk + **/ + PROCEDURE EXPORT_PARTITION_PARALLEL ( + pStartId IN NUMBER, + pEndId IN NUMBER, + pTaskName IN VARCHAR2 DEFAULT NULL + ) IS + vYear VARCHAR2(4); + vMonth VARCHAR2(2); + vSchemaName VARCHAR2(128); + vTableName VARCHAR2(128); + vKeyColumnName VARCHAR2(128); + vBucketUri VARCHAR2(4000); + vFolderName VARCHAR2(1000); + vProcessedColumns VARCHAR2(32767); + vMinDate DATE; + vMaxDate DATE; + vCredentialName VARCHAR2(200); + vFormat VARCHAR2(20); + vFileBaseName VARCHAR2(1000); + vMaxFileSize NUMBER; + vJobClass VARCHAR2(128); + vTaskName VARCHAR2(128); + vParameters VARCHAR2(4000); + BEGIN + -- Retrieve chunk context from A_PARALLEL_EXPORT_CHUNKS table + -- CRITICAL: Filter by CHUNK_ID and TASK_NAME for precise session isolation + -- pTaskName parameter passed from RUN_TASK ensures deterministic single-row retrieval + SELECT + YEAR_VALUE, + MONTH_VALUE, + SCHEMA_NAME, + TABLE_NAME, + KEY_COLUMN_NAME, + BUCKET_URI, + FOLDER_NAME, + PROCESSED_COLUMNS, + MIN_DATE, + MAX_DATE, + CREDENTIAL_NAME, + FORMAT_TYPE, + FILE_BASE_NAME, + MAX_FILE_SIZE, + JOB_CLASS, + TASK_NAME + INTO + vYear, + vMonth, + vSchemaName, + vTableName, + vKeyColumnName, + vBucketUri, + vFolderName, + vProcessedColumns, + vMinDate, + vMaxDate, + vCredentialName, + vFormat, + vFileBaseName, + vMaxFileSize, + vJobClass, + vTaskName + FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS + WHERE CHUNK_ID = pStartId + AND TASK_NAME = pTaskName; + + vParameters := 'Parallel task - Year: ' || vYear || ', Month: ' || vMonth || ', ChunkID: ' || pStartId || ', TaskName: ' || vTaskName; + ENV_MANAGER.LOG_PROCESS_EVENT('Starting parallel export for partition ' || vYear || '/' || vMonth, 'DEBUG', vParameters); + + -- Mark chunk as PROCESSING + -- CRITICAL: Use both CHUNK_ID AND TASK_NAME for session isolation + UPDATE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS + SET STATUS = 'PROCESSING', + ERROR_MESSAGE = NULL + WHERE CHUNK_ID = pStartId + AND TASK_NAME = vTaskName; + COMMIT; + + -- Call the worker procedure + EXPORT_SINGLE_PARTITION( + pSchemaName => vSchemaName, + pTableName => vTableName, + pKeyColumnName => vKeyColumnName, + pYear => vYear, + pMonth => vMonth, + pBucketUri => vBucketUri, + pFolderName => vFolderName, + pProcessedColumns => vProcessedColumns, + pMinDate => vMinDate, + pMaxDate => vMaxDate, + pCredentialName => vCredentialName, + pFormat => vFormat, + pFileBaseName => vFileBaseName, + pMaxFileSize => vMaxFileSize, + pParameters => vParameters + ); + + -- Mark chunk as COMPLETED + -- CRITICAL: Use both CHUNK_ID AND TASK_NAME for session isolation + UPDATE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS + SET STATUS = 'COMPLETED', + EXPORT_TIMESTAMP = SYSTIMESTAMP, + ERROR_MESSAGE = NULL + WHERE CHUNK_ID = pStartId + AND TASK_NAME = vTaskName; + COMMIT; + + ENV_MANAGER.LOG_PROCESS_EVENT('Completed parallel export for partition ' || vYear || '/' || vMonth, 'DEBUG', vParameters); + EXCEPTION + WHEN OTHERS THEN + -- Capture error details in variable (SQLERRM cannot be used directly in SQL) + vgMsgTmp := 'Parallel task error for partition ' || vYear || '/' || vMonth || ' (ChunkID: ' || pStartId || ', TaskName: ' || vTaskName || '): ' || SQLERRM || cgBL || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + + -- Mark chunk as FAILED with error message + -- CRITICAL: Use both CHUNK_ID AND TASK_NAME for session isolation + -- Use vgMsgTmp variable instead of SQLERRM directly (Oracle limitation in SQL context) + UPDATE CT_MRDS.A_PARALLEL_EXPORT_CHUNKS + SET STATUS = 'FAILED', + ERROR_MESSAGE = SUBSTR(vgMsgTmp, 1, 4000) + WHERE CHUNK_ID = pStartId + AND TASK_NAME = vTaskName; + COMMIT; + + RAISE; + END EXPORT_PARTITION_PARALLEL; + + ---------------------------------------------------------------------------------------------------- + -- MAIN EXPORT PROCEDURES + ---------------------------------------------------------------------------------------------------- + + PROCEDURE EXPORT_TABLE_DATA ( + pSchemaName IN VARCHAR2, + pTableName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pBucketArea IN VARCHAR2, + pFolderName IN VARCHAR2, + pFileName IN VARCHAR2 default NULL, + pTemplateTableName IN VARCHAR2 default NULL, + pMaxFileSize IN NUMBER default 104857600, + pRegisterExport IN BOOLEAN default FALSE, + pProcessName IN VARCHAR2 default 'DATA_EXPORTER', + pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName + ) + IS + vCount INTEGER; + vQuery VARCHAR2(32767); + vUri VARCHAR2(4000); + vTableName VARCHAR2(128); + vSchemaName VARCHAR2(128); + vKeyColumnName VARCHAR2(128); + vParameters VARCHAR2(4000); + vBucketUri VARCHAR2(4000); + vProcessedColumnList VARCHAR2(32767); + vCurrentCol VARCHAR2(128); + + -- Variables for file registration (when pRegisterExport=TRUE) + vConfigKey NUMBER; + vSourceKey VARCHAR2(100); + vTableId VARCHAR2(100); + vSlashPos1 NUMBER; + vSlashPos2 NUMBER; + vSourceFileReceivedKey NUMBER; + + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( 'pSchemaName => '''||nvl(pSchemaName, 'NULL')||'''' + ,'pTableName => '''||nvl(pTableName, 'NULL')||'''' + ,'pKeyColumnName => '''||nvl(pKeyColumnName, 'NULL')||'''' + ,'pBucketArea => '''||nvl(pBucketArea, 'NULL')||'''' + ,'pFolderName => '''||nvl(pFolderName, 'NULL')||'''' + ,'pFileName => '''||nvl(pFileName, 'NULL')||'''' + ,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||'''' + ,'pMaxFileSize => '''||nvl(TO_CHAR(pMaxFileSize), 'NULL')||'''' + ,'pRegisterExport => '''||CASE WHEN pRegisterExport THEN 'TRUE' ELSE 'FALSE' END||'''' + ,'pProcessName => '''||nvl(pProcessName, 'NULL')||'''' + ,'pCredentialName => '''||nvl(pCredentialName, 'NULL')||'''' + )); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + -- Get bucket URI based on bucket area using FILE_MANAGER function + vBucketUri := FILE_MANAGER.GET_BUCKET_URI(pBucketArea); + + -- Convert table and column names to uppercase to match data dictionary + vTableName := UPPER(pTableName); + vSchemaName := UPPER(pSchemaName); + vKeyColumnName := UPPER(pKeyColumnName); + + -- Check if table exists + SELECT COUNT(*) INTO vCount + FROM all_tables + WHERE table_name = vTableName + AND owner = vSchemaName; + + IF vCount = 0 THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_TABLE_NOT_EXISTS, ENV_MANAGER.MSG_TABLE_NOT_EXISTS); + END IF; + + -- Check if key column exists + SELECT COUNT(*) INTO vCount + FROM all_tab_columns + WHERE table_name = vTableName + AND column_name = vKeyColumnName + AND owner = vSchemaName; + + IF vCount = 0 THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_COLUMN_NOT_EXISTS, ENV_MANAGER.MSG_COLUMN_NOT_EXISTS); + END IF; + + -- Validate template table if provided + IF pTemplateTableName IS NOT NULL THEN + DECLARE + vTemplateSchema VARCHAR2(128); + vTemplateTable VARCHAR2(128); + vTemplateCount NUMBER; + BEGIN + -- Parse template table name (SCHEMA.TABLE or just TABLE) + IF INSTR(pTemplateTableName, '.') > 0 THEN + vTemplateSchema := UPPER(SUBSTR(pTemplateTableName, 1, INSTR(pTemplateTableName, '.') - 1)); + vTemplateTable := UPPER(SUBSTR(pTemplateTableName, INSTR(pTemplateTableName, '.') + 1)); + ELSE + vTemplateSchema := vSchemaName; + vTemplateTable := UPPER(pTemplateTableName); + END IF; + + -- Check if template table exists + SELECT COUNT(*) INTO vTemplateCount + FROM all_tables + WHERE table_name = vTemplateTable + AND owner = vTemplateSchema; + + IF vTemplateCount = 0 THEN + vgMsgTmp := ENV_MANAGER.MSG_TABLE_NOT_EXISTS || ': Template table ' || vTemplateSchema || '.' || vTemplateTable; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_TABLE_NOT_EXISTS, vgMsgTmp); + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('Template table validated: ' || vTemplateSchema || '.' || vTemplateTable, 'DEBUG', vParameters); + END; + END IF; + + -- Build query with TO_CHAR for date columns (per-column format support) + vProcessedColumnList := buildQueryWithDateFormats(NULL, vTableName, vSchemaName, vKeyColumnName, pTemplateTableName); + + ENV_MANAGER.LOG_PROCESS_EVENT('Processed column list with TO_CHAR for date columns: ' || vProcessedColumnList, 'DEBUG', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Template table: ' || NVL(pTemplateTableName, 'NULL - using global default for all dates'), 'INFO', vParameters); + + vTableName := DBMS_ASSERT.SCHEMA_NAME(vSchemaName) || '.' || DBMS_ASSERT.simple_sql_name(vTableName); + + -- Lookup A_SOURCE_FILE_CONFIG_KEY based on pFolderName parsing if pRegisterExport is enabled + IF pRegisterExport THEN + -- Format: {BUCKET_AREA}/{SOURCE_KEY}/{TABLE_ID} + -- Example: 'ODS/CSDB/CSDB_DEBT_DAILY' -> SOURCE_KEY='CSDB', TABLE_ID='CSDB_DEBT_DAILY' + + -- Parse pFolderName to extract SOURCE_KEY and TABLE_ID + vSlashPos1 := INSTR(pFolderName, '/', 1, 1); -- First '/' position + vSlashPos2 := INSTR(pFolderName, '/', 1, 2); -- Second '/' position + + IF vSlashPos1 > 0 AND vSlashPos2 > 0 THEN + -- Extract segment 2 (SOURCE_KEY) and segment 3 (TABLE_ID) + vSourceKey := SUBSTR(pFolderName, vSlashPos1 + 1, vSlashPos2 - vSlashPos1 - 1); + vTableId := SUBSTR(pFolderName, vSlashPos2 + 1); + + -- Find configuration based on SOURCE_KEY and TABLE_ID + BEGIN + SELECT A_SOURCE_FILE_CONFIG_KEY + INTO vConfigKey + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE A_SOURCE_KEY = vSourceKey + AND TABLE_ID = vTableId + AND SOURCE_FILE_TYPE = 'INPUT' + AND ROWNUM = 1; + + ENV_MANAGER.LOG_PROCESS_EVENT('Found config key: ' || vConfigKey || ' for SOURCE=' || vSourceKey || ', TABLE=' || vTableId, 'DEBUG', vParameters); + EXCEPTION + WHEN NO_DATA_FOUND THEN + vConfigKey := -1; + ENV_MANAGER.LOG_PROCESS_EVENT('No config found for SOURCE=' || vSourceKey || ', TABLE=' || vTableId || ' - using default (-1)', 'INFO', vParameters); + END; + ELSE + -- Cannot parse folder name - use default + vConfigKey := -1; + ENV_MANAGER.LOG_PROCESS_EVENT('Cannot parse pFolderName: ' || pFolderName || ' - using default (-1)', 'WARNING', vParameters); + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('File registration enabled with config key: ' || vConfigKey, 'INFO', vParameters); + END IF; + + -- Construct single query for entire table (no join with A_LOAD_HISTORY - ensures single file output) + vQuery := 'SELECT ' || vProcessedColumnList || + ' FROM ' || vTableName || ' T'; + + -- Construct the URI for the file in OCI Object Storage + vUri := vBucketUri || + CASE WHEN pFolderName IS NOT NULL THEN pFolderName || '/' ELSE '' END || + NVL(pFileName, UPPER(vTableName) || '.csv'); + + ENV_MANAGER.LOG_PROCESS_EVENT('Exporting to single file: ' || vUri, 'INFO', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Export query: ' || vQuery, 'DEBUG', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Max file size: ' || pMaxFileSize || ' bytes (' || ROUND(pMaxFileSize/1048576, 2) || ' MB)', 'DEBUG', vParameters); + + -- Use DBMS_CLOUD package to export data to the URI + -- Oracle maxfilesize: min 10MB (10485760), max 1GB (1073741824), default 100MB (104857600) + DBMS_CLOUD.EXPORT_DATA( + credential_name => pCredentialName, + file_uri_list => vUri, + query => vQuery, + format => json_object( + 'type' VALUE 'CSV', + 'header' VALUE true, + 'quote' VALUE CHR(34), + 'delimiter' VALUE ',', + 'escape' VALUE true, + 'recorddelimiter' VALUE CHR(13)||CHR(10), -- CRLF dla Windows + 'maxfilesize' VALUE pMaxFileSize -- Dynamic maxfilesize in bytes + ) + ); + + -- Register exported file to A_SOURCE_FILE_RECEIVED if requested + IF pRegisterExport THEN + DECLARE + vActualFileName VARCHAR2(1000); -- Actual filename with Oracle suffix + vSanitizedFileName VARCHAR2(1000); + vFileName VARCHAR2(1000); + vRetryCount NUMBER := 0; + vMaxRetries NUMBER := 1; -- One retry after initial attempt + vRetryDelay NUMBER := 2; -- 2 seconds delay + vFilesFound NUMBER := 0; + vTotalBytes NUMBER := 0; + BEGIN + -- Extract filename from URI (after last '/') + vFileName := SUBSTR(vUri, INSTR(vUri, '/', -1) + 1); + + -- Sanitize filename first (PL/SQL function cannot be used directly in SQL) + vSanitizedFileName := sanitizeFilename(vFileName); + + -- Remove .csv extension for LIKE pattern matching (Oracle adds suffixes BEFORE .csv) + -- Example: tablename.csv becomes tablename_1_20260211T102621591769Z.csv + vSanitizedFileName := REGEXP_REPLACE(vSanitizedFileName, '\.csv$', '', 1, 0, 'i'); + + -- Try to get ALL exported files with retry logic + -- Oracle DBMS_CLOUD.EXPORT_DATA can create MULTIPLE files due to: + -- 1. maxfilesize parameter (splits files larger than limit) + -- 2. Automatic parallel processing (especially on large production instances) + -- We must register ALL files, not just the first one + <> + LOOP + BEGIN + -- Register ALL files matching the pattern (cursor loop) + FOR rec IN ( + SELECT object_name, checksum, created, bytes + FROM TABLE(DBMS_CLOUD.LIST_OBJECTS( + credential_name => pCredentialName, + location_uri => vBucketUri + )) + WHERE object_name LIKE CASE WHEN pFolderName IS NOT NULL THEN pFolderName || '/' ELSE '' END || vSanitizedFileName || '%' + ORDER BY created DESC, bytes DESC + ) LOOP + -- Extract filename only from full path (remove bucket folder prefix) + vActualFileName := SUBSTR(rec.object_name, INSTR(rec.object_name, '/', -1) + 1); + + -- Create A_SOURCE_FILE_RECEIVED record for EACH exported file + vSourceFileReceivedKey := CT_MRDS.A_SOURCE_FILE_RECEIVED_KEY_SEQ.NEXTVAL; + INSERT INTO CT_MRDS.A_SOURCE_FILE_RECEIVED ( + A_SOURCE_FILE_RECEIVED_KEY, + A_SOURCE_FILE_CONFIG_KEY, + SOURCE_FILE_NAME, + CHECKSUM, + CREATED, + BYTES, + RECEPTION_DATE, + PROCESSING_STATUS, + PARTITION_YEAR, + PARTITION_MONTH, + ARCH_PATH, + PROCESS_NAME + ) VALUES ( + vSourceFileReceivedKey, + NVL(vConfigKey, -1), -- Use config key if found, otherwise -1 + vActualFileName, -- Use actual filename with Oracle suffix + rec.checksum, + rec.created, + rec.bytes, + SYSDATE, + 'INGESTED', + NULL, -- PARTITION_YEAR not used for single-file exports + NULL, -- PARTITION_MONTH not used for single-file exports + NULL, -- ARCH_PATH not used for single-file exports + pProcessName -- Process name from parameter + ); + + vFilesFound := vFilesFound + 1; + vTotalBytes := vTotalBytes + rec.bytes; + + ENV_MANAGER.LOG_PROCESS_EVENT('Registered file ' || vFilesFound || ': FileReceivedKey=' || vSourceFileReceivedKey || ', File=' || vActualFileName || ', Size=' || rec.bytes || ' bytes', 'INFO', vParameters); + END LOOP; + + -- Check if any files were found + IF vFilesFound = 0 THEN + RAISE NO_DATA_FOUND; + END IF; + + -- Success - exit retry loop + ENV_MANAGER.LOG_PROCESS_EVENT('Total registered: ' || vFilesFound || ' file(s), Total size: ' || vTotalBytes || ' bytes (' || ROUND(vTotalBytes/1048576, 2) || ' MB)', 'INFO', vParameters); + EXIT metadata_retry_loop; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + vRetryCount := vRetryCount + 1; + + IF vRetryCount <= vMaxRetries THEN + -- Log retry attempt + ENV_MANAGER.LOG_PROCESS_EVENT('File(s) not found in bucket (attempt ' || vRetryCount || '/' || (vMaxRetries + 1) || '), retrying after ' || vRetryDelay || ' seconds: ' || vFileName, 'DEBUG', vParameters); + + -- Wait before retry using DBMS_SESSION.SLEEP (alternative to DBMS_LOCK) + DBMS_SESSION.SLEEP(vRetryDelay); + ELSE + -- Max retries exceeded - re-raise exception + RAISE; + END IF; + END; + END LOOP metadata_retry_loop; + EXCEPTION + WHEN NO_DATA_FOUND THEN + -- File not found after retries - log warning and continue without metadata + ENV_MANAGER.LOG_PROCESS_EVENT('WARNING: File not found in bucket after ' || (vMaxRetries + 1) || ' attempts: ' || vFileName, 'WARNING', vParameters); + + -- Sanitize filename for fallback INSERT (function cannot be used in SQL) + vSanitizedFileName := sanitizeFilename(vFileName); + + -- Insert without metadata using theoretical filename + vSourceFileReceivedKey := CT_MRDS.A_SOURCE_FILE_RECEIVED_KEY_SEQ.NEXTVAL; + INSERT INTO CT_MRDS.A_SOURCE_FILE_RECEIVED ( + A_SOURCE_FILE_RECEIVED_KEY, + A_SOURCE_FILE_CONFIG_KEY, + SOURCE_FILE_NAME, + RECEPTION_DATE, + PROCESSING_STATUS, + PARTITION_YEAR, + PARTITION_MONTH, + ARCH_PATH, + PROCESS_NAME + ) VALUES ( + vSourceFileReceivedKey, + NVL(vConfigKey, -1), -- Use config key if found, otherwise -1 + vSanitizedFileName, -- Use pre-calculated sanitized filename + SYSDATE, + 'INGESTED', + NULL, -- PARTITION_YEAR not used for single-file exports + NULL, -- PARTITION_MONTH not used for single-file exports + NULL, -- ARCH_PATH not used for single-file exports + pProcessName -- Process name from parameter + ); + + ENV_MANAGER.LOG_PROCESS_EVENT('Registered file without metadata: FileReceivedKey=' || vSourceFileReceivedKey || ', File=' || vSanitizedFileName, 'INFO', vParameters); + END; + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + EXCEPTION + WHEN ENV_MANAGER.ERR_TABLE_NOT_EXISTS THEN + vgMsgTmp := ENV_MANAGER.MSG_TABLE_NOT_EXISTS ||': '||vTableName; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_TABLE_NOT_EXISTS, vgMsgTmp); + WHEN ENV_MANAGER.ERR_COLUMN_NOT_EXISTS THEN + vgMsgTmp := ENV_MANAGER.MSG_COLUMN_NOT_EXISTS || ' (TableName.ColumnName): ' || vTableName||'.'||vKeyColumnName||CASE WHEN vCurrentCol IS NOT NULL THEN '.'||vCurrentCol||' in column list' ELSE '' END; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_COLUMN_NOT_EXISTS, vgMsgTmp); + WHEN OTHERS THEN + -- Log complete error details including full stack trace and backtrace + ENV_MANAGER.LOG_PROCESS_ERROR('Export failed: ' || SQLERRM, vParameters, 'DATA_EXPORTER'); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + + END EXPORT_TABLE_DATA; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE EXPORT_TABLE_DATA_BY_DATE ( + pSchemaName IN VARCHAR2, + pTableName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pBucketArea IN VARCHAR2, + pFolderName IN VARCHAR2, + pColumnList IN VARCHAR2 default NULL, + pMinDate IN DATE default DATE '1900-01-01', + pMaxDate IN DATE default SYSDATE, + pParallelDegree IN NUMBER default 1, + pTemplateTableName IN VARCHAR2 default NULL, + pJobClass IN VARCHAR2 default NULL, + pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName + ) + IS + vTableName VARCHAR2(128); + vSchemaName VARCHAR2(128); + vKeyColumnName VARCHAR2(128); + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vProcessedColumnList VARCHAR2(32767); + vBucketUri VARCHAR2(4000); + vCurrentCol VARCHAR2(128); + vPartitions partition_tab; + + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( 'pSchemaName => '''||nvl(pSchemaName, 'NULL')||'''' + ,'pTableName => '''||nvl(pTableName, 'NULL')||'''' + ,'pKeyColumnName => '''||nvl(pKeyColumnName, 'NULL')||'''' + ,'pBucketArea => '''||nvl(pBucketArea, 'NULL')||'''' + ,'pFolderName => '''||nvl(pFolderName, 'NULL')||'''' + ,'pColumnList => '''||nvl(pColumnList, 'NULL')||'''' + ,'pMinDate => '''||nvl(TO_CHAR(pMinDate, 'YYYY-MM-DD HH24:MI:SS'), 'NULL')||'''' + ,'pMaxDate => '''||nvl(TO_CHAR(pMaxDate, 'YYYY-MM-DD HH24:MI:SS'), 'NULL')||'''' + ,'pParallelDegree => '''||nvl(TO_CHAR(pParallelDegree), 'NULL')||'''' + ,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||'''' + ,'pJobClass => '''||nvl(pJobClass, 'NULL')||'''' + ,'pCredentialName => '''||nvl(pCredentialName, 'NULL')||'''' + )); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + -- Get bucket URI based on bucket area using FILE_MANAGER function + vBucketUri := FILE_MANAGER.GET_BUCKET_URI(pBucketArea); + + -- Convert table and column names to uppercase to match data dictionary + vTableName := UPPER(pTableName); + vSchemaName := UPPER(pSchemaName); + vKeyColumnName := UPPER(pKeyColumnName); + + -- Validate table, key column, and column list using shared procedure + VALIDATE_TABLE_AND_COLUMNS(vSchemaName, vTableName, vKeyColumnName, pColumnList, vParameters); + + -- Build query with TO_CHAR for date columns (per-column format support) + vProcessedColumnList := buildQueryWithDateFormats(pColumnList, vTableName, vSchemaName, vKeyColumnName, pTemplateTableName); + + ENV_MANAGER.LOG_PROCESS_EVENT('Input column list: ' || NVL(pColumnList, 'NULL (building dynamic list from table metadata)'), 'DEBUG', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Processed column list with TO_CHAR for date columns: ' || vProcessedColumnList, 'DEBUG', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Template table: ' || NVL(pTemplateTableName, 'NULL - using global default for all dates'), 'INFO', vParameters); + + vTableName := DBMS_ASSERT.SCHEMA_NAME(vSchemaName) || '.' || DBMS_ASSERT.simple_sql_name(vTableName); + + -- Validate parallel degree parameter + IF pParallelDegree < 1 OR pParallelDegree > 16 THEN + vgMsgTmp := ENV_MANAGER.MSG_INVALID_PARALLEL_DEGREE || ': ' || pParallelDegree || '. Valid range: 1-16'; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_INVALID_PARALLEL_DEGREE, vgMsgTmp); + END IF; + + -- Get partitions using shared function + vPartitions := GET_PARTITIONS(vSchemaName, vTableName, vKeyColumnName, pMinDate, pMaxDate, vParameters); + + ENV_MANAGER.LOG_PROCESS_EVENT('Found ' || vPartitions.COUNT || ' partitions to export with parallel degree ' || pParallelDegree, 'INFO', vParameters); + + -- Sequential processing (parallel degree = 1) + IF pParallelDegree = 1 THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Using sequential processing (pParallelDegree = 1)', 'DEBUG', vParameters); + + FOR i IN 1 .. vPartitions.COUNT LOOP + EXPORT_SINGLE_PARTITION( + pSchemaName => vSchemaName, + pTableName => vTableName, + pKeyColumnName => vKeyColumnName, + pYear => vPartitions(i).year, + pMonth => vPartitions(i).month, + pBucketUri => vBucketUri, + pFolderName => pFolderName, + pProcessedColumns => vProcessedColumnList, + pMinDate => pMinDate, + pMaxDate => pMaxDate, + pCredentialName => pCredentialName, + pFormat => 'PARQUET', + pFileBaseName => NULL, + pMaxFileSize => 104857600, + pParameters => vParameters + ); + END LOOP; + + -- Parallel processing (parallel degree > 1) + ELSE + -- Skip parallel processing if no partitions found + IF vPartitions.COUNT = 0 THEN + ENV_MANAGER.LOG_PROCESS_EVENT('No partitions to export - skipping parallel processing', 'INFO', vParameters); + ELSE + DECLARE + vTaskName VARCHAR2(128) := 'DATA_EXPORT_TASK_' || TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISSFF'); + vChunkId NUMBER; + BEGIN + ENV_MANAGER.LOG_PROCESS_EVENT('Using parallel processing with ' || pParallelDegree || ' threads', 'INFO', vParameters); + + -- Populate chunks table (insert new chunks, preserve FAILED chunks for retry) + FOR i IN 1 .. vPartitions.COUNT LOOP + MERGE INTO CT_MRDS.A_PARALLEL_EXPORT_CHUNKS t + USING (SELECT i AS chunk_id, vTaskName AS task_name, vPartitions(i).year AS yr, vPartitions(i).month AS mn FROM DUAL) s + ON (t.CHUNK_ID = s.chunk_id AND t.TASK_NAME = s.task_name) + WHEN NOT MATCHED THEN + INSERT (CHUNK_ID, TASK_NAME, YEAR_VALUE, MONTH_VALUE, SCHEMA_NAME, TABLE_NAME, KEY_COLUMN_NAME, + BUCKET_URI, FOLDER_NAME, PROCESSED_COLUMNS, MIN_DATE, MAX_DATE, + CREDENTIAL_NAME, FORMAT_TYPE, FILE_BASE_NAME, TEMPLATE_TABLE_NAME, MAX_FILE_SIZE, JOB_CLASS, STATUS) + VALUES (i, vTaskName, vPartitions(i).year, vPartitions(i).month, vSchemaName, vTableName, vKeyColumnName, + vBucketUri, pFolderName, vProcessedColumnList, pMinDate, pMaxDate, + pCredentialName, 'PARQUET', NULL, pTemplateTableName, 104857600, pJobClass, 'PENDING') + WHEN MATCHED THEN + -- Match found: chunk exists for SAME task (composite PK: TASK_NAME, CHUNK_ID) + -- This handles retry scenario: reset FAILED chunks to PENDING for re-processing + UPDATE SET STATUS = CASE WHEN t.STATUS = 'FAILED' THEN 'PENDING' ELSE t.STATUS END, + ERROR_MESSAGE = CASE WHEN t.STATUS = 'FAILED' THEN NULL ELSE t.ERROR_MESSAGE END; + END LOOP; + COMMIT; + + -- Log chunk statistics (session-safe: only count chunks for THIS task) + DECLARE + vPendingCount NUMBER; + vFailedCount NUMBER; + BEGIN + SELECT COUNT(*) INTO vPendingCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'PENDING' AND TASK_NAME = vTaskName; + SELECT COUNT(*) INTO vFailedCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'FAILED' AND TASK_NAME = vTaskName; + + ENV_MANAGER.LOG_PROCESS_EVENT('Chunk statistics for task ' || vTaskName || ': PENDING=' || vPendingCount || ', FAILED (retry)=' || vFailedCount, 'INFO', vParameters); + END; + + -- Create parallel task + DBMS_PARALLEL_EXECUTE.CREATE_TASK(task_name => vTaskName); + + -- Define chunks using SQL query to ensure TASK_NAME isolation + -- CRITICAL: Filter by TASK_NAME to avoid selecting chunks from other concurrent sessions + -- CRITICAL: Use START_ID and END_ID aliases to avoid ORA-00960 ambiguous column naming + DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_SQL( + task_name => vTaskName, + sql_stmt => 'SELECT CHUNK_ID AS START_ID, CHUNK_ID AS END_ID FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE TASK_NAME = ''' || vTaskName || ''' ORDER BY CHUNK_ID', + by_rowid => FALSE + ); + + -- Execute task in parallel + ENV_MANAGER.LOG_PROCESS_EVENT('Executing parallel task: ' || vTaskName || CASE WHEN pJobClass IS NOT NULL THEN ' with job class: ' || pJobClass ELSE '' END, 'DEBUG', vParameters); + + IF pJobClass IS NOT NULL THEN + DBMS_PARALLEL_EXECUTE.RUN_TASK( + task_name => vTaskName, + sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id, ''' || vTaskName || '''); END;', + language_flag => DBMS_SQL.NATIVE, + parallel_level => pParallelDegree, + job_class => pJobClass + ); + ELSE + DBMS_PARALLEL_EXECUTE.RUN_TASK( + task_name => vTaskName, + sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id, ''' || vTaskName || '''); END;', + language_flag => DBMS_SQL.NATIVE, + parallel_level => pParallelDegree + ); + END IF; + + -- Check for errors + DECLARE + vErrorCount NUMBER; + BEGIN + SELECT COUNT(*) INTO vErrorCount + FROM USER_PARALLEL_EXECUTE_CHUNKS + WHERE task_name = vTaskName AND status = 'PROCESSED_WITH_ERROR'; + + IF vErrorCount > 0 THEN + vgMsgTmp := 'Parallel execution completed with ' || vErrorCount || ' errors. Check USER_PARALLEL_EXECUTE_CHUNKS for details.'; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_PARALLEL_EXECUTION_FAILED, vgMsgTmp); + END IF; + END; + + -- Clean up task + DBMS_PARALLEL_EXECUTE.DROP_TASK(task_name => vTaskName); + + -- Clean up chunks for THIS specific task only (session-safe) + -- CRITICAL: Use TASK_NAME filter to avoid deleting chunks from other active sessions + DELETE FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE TASK_NAME = vTaskName; + COMMIT; + + ENV_MANAGER.LOG_PROCESS_EVENT('Parallel execution completed successfully', 'INFO', vParameters); + EXCEPTION + WHEN OTHERS THEN + -- Attempt to drop task on error + BEGIN + DBMS_PARALLEL_EXECUTE.DROP_TASK(task_name => vTaskName); + EXCEPTION + WHEN OTHERS THEN NULL; -- Ignore drop errors + END; + + vgMsgTmp := ENV_MANAGER.MSG_PARALLEL_EXECUTION_FAILED || ': ' || SQLERRM || cgBL || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_PARALLEL_EXECUTION_FAILED, vgMsgTmp); + END; + END IF; + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + EXCEPTION + WHEN ENV_MANAGER.ERR_TABLE_NOT_EXISTS THEN + vgMsgTmp := ENV_MANAGER.MSG_TABLE_NOT_EXISTS ||': '||vTableName; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_TABLE_NOT_EXISTS, vgMsgTmp); + WHEN ENV_MANAGER.ERR_COLUMN_NOT_EXISTS THEN + vgMsgTmp := ENV_MANAGER.MSG_COLUMN_NOT_EXISTS || ' (TableName.ColumnName): ' || vTableName||'.'||vKeyColumnName||CASE WHEN vCurrentCol IS NOT NULL THEN '.'||vCurrentCol||' in pColumnList' ELSE '' END; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_COLUMN_NOT_EXISTS, vgMsgTmp); + WHEN ENV_MANAGER.ERR_INVALID_PARALLEL_DEGREE THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_INVALID_PARALLEL_DEGREE, vgMsgTmp); + WHEN ENV_MANAGER.ERR_PARALLEL_EXECUTION_FAILED THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_PARALLEL_EXECUTION_FAILED, vgMsgTmp); + WHEN OTHERS THEN + -- Log complete error details including full stack trace and backtrace + ENV_MANAGER.LOG_PROCESS_ERROR('Export failed: ' || SQLERRM, vParameters, 'DATA_EXPORTER'); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + + END EXPORT_TABLE_DATA_BY_DATE; + + ---------------------------------------------------------------------------------------------------- + + /** + * @name EXPORT_TABLE_DATA_TO_CSV_BY_DATE + * @desc Exports data to a single CSV file with date filtering. + * Unlike EXPORT_TABLE_DATA_BY_DATE, this procedure creates one CSV file + * instead of multiple Parquet files partitioned by year/month. + * Uses the same date filtering mechanism with CT_ODS.A_LOAD_HISTORY. + * Allows specifying custom column list or uses T.* if pColumnList is NULL. + * Validates that all columns in pColumnList exist in the target table. + * Automatically adds 'T.' prefix to column names in pColumnList. + * @example + * begin + * DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE( + * pSchemaName => 'CT_MRDS', + * pTableName => 'MY_TABLE', + * pKeyColumnName => 'A_ETL_LOAD_SET_KEY_FK', + * pBucketArea => 'DATA', + * pFolderName => 'exports', + * pFileName => 'my_export.csv', + * pColumnList => 'COLUMN1, COLUMN2, COLUMN3', -- Optional + * pMinDate => DATE '2024-01-01', + * pMaxDate => SYSDATE + * ); + * end; + **/ + PROCEDURE EXPORT_TABLE_DATA_TO_CSV_BY_DATE ( + pSchemaName IN VARCHAR2, + pTableName IN VARCHAR2, + pKeyColumnName IN VARCHAR2, + pBucketArea IN VARCHAR2, + pFolderName IN VARCHAR2, + pFileName IN VARCHAR2 DEFAULT NULL, + pColumnList IN VARCHAR2 default NULL, + pMinDate IN DATE default DATE '1900-01-01', + pMaxDate IN DATE default SYSDATE, + pParallelDegree IN NUMBER default 1, + pTemplateTableName IN VARCHAR2 default NULL, + pMaxFileSize IN NUMBER default 104857600, + pRegisterExport IN BOOLEAN default FALSE, + pProcessName IN VARCHAR2 default 'DATA_EXPORTER', + pJobClass IN VARCHAR2 default NULL, + pCredentialName IN VARCHAR2 default ENV_MANAGER.gvCredentialName + ) + IS + vTableName VARCHAR2(128); + vSchemaName VARCHAR2(128); + vKeyColumnName VARCHAR2(128); + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vFileBaseName VARCHAR2(4000); + vFileExtension VARCHAR2(10); + vProcessedColumnList VARCHAR2(32767); + vBucketUri VARCHAR2(4000); + vCurrentCol VARCHAR2(128); + vPartitions partition_tab; + vSourceFileReceivedKey NUMBER; + vFileName VARCHAR2(1000); + vFileUri VARCHAR2(4000); + -- Variables for A_SOURCE_FILE_CONFIG lookup + vSourceKey VARCHAR2(100); + vTableId VARCHAR2(200); + vConfigKey NUMBER := -1; + vSlashPos1 NUMBER; + vSlashPos2 NUMBER; + + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( 'pSchemaName => '''||nvl(pSchemaName, 'NULL')||'''' + ,'pTableName => '''||nvl(pTableName, 'NULL')||'''' + ,'pKeyColumnName => '''||nvl(pKeyColumnName, 'NULL')||'''' + ,'pBucketArea => '''||nvl(pBucketArea, 'NULL')||'''' + ,'pFolderName => '''||nvl(pFolderName, 'NULL')||'''' + ,'pFileName => '''||nvl(pFileName, 'NULL')||'''' + ,'pColumnList => '''||nvl(pColumnList, 'NULL')||'''' + ,'pMinDate => '''||nvl(TO_CHAR(pMinDate, 'YYYY-MM-DD HH24:MI:SS'), 'NULL')||'''' + ,'pMaxDate => '''||nvl(TO_CHAR(pMaxDate, 'YYYY-MM-DD HH24:MI:SS'), 'NULL')||'''' + ,'pParallelDegree => '''||nvl(TO_CHAR(pParallelDegree), 'NULL')||'''' + ,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||'''' + ,'pMaxFileSize => '''||nvl(TO_CHAR(pMaxFileSize), 'NULL')||'''' + ,'pRegisterExport => '''||CASE WHEN pRegisterExport THEN 'TRUE' ELSE 'FALSE' END||'''' + ,'pJobClass => '''||nvl(pJobClass, 'NULL')||'''' + ,'pCredentialName => '''||nvl(pCredentialName, 'NULL')||'''' + )); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + -- Get bucket URI based on bucket area using FILE_MANAGER function + vBucketUri := FILE_MANAGER.GET_BUCKET_URI(pBucketArea); + + -- Convert table and column names to uppercase to match data dictionary + vTableName := UPPER(pTableName); + vSchemaName := UPPER(pSchemaName); + vKeyColumnName := UPPER(pKeyColumnName); + + -- Extract base filename and extension or construct default filename + IF pFileName IS NOT NULL THEN + -- Use provided filename + IF INSTR(pFileName, '.') > 0 THEN + vFileBaseName := SUBSTR(pFileName, 1, INSTR(pFileName, '.', -1) - 1); + vFileExtension := SUBSTR(pFileName, INSTR(pFileName, '.', -1)); + ELSE + vFileBaseName := pFileName; + vFileExtension := '.csv'; + END IF; + ELSE + -- Construct default filename: TABLENAME (without extension, will be added by worker) + vFileBaseName := UPPER(pTableName); + vFileExtension := '.csv'; + END IF; + + -- Validate table, key column, and column list using shared procedure + VALIDATE_TABLE_AND_COLUMNS(vSchemaName, vTableName, vKeyColumnName, pColumnList, vParameters); + + -- Build query with TO_CHAR for date columns (per-column format support) + vProcessedColumnList := buildQueryWithDateFormats(pColumnList, vTableName, vSchemaName, vKeyColumnName, pTemplateTableName); + + ENV_MANAGER.LOG_PROCESS_EVENT('Input column list: ' || NVL(pColumnList, 'NULL (using dynamic column list)'), 'DEBUG', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Processed column list with TO_CHAR for date columns: ' || vProcessedColumnList, 'DEBUG', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Template table: ' || NVL(pTemplateTableName, 'NULL - using global default for all dates'), 'INFO', vParameters); + + vTableName := DBMS_ASSERT.SCHEMA_NAME(vSchemaName) || '.' || DBMS_ASSERT.simple_sql_name(vTableName); + + -- Validate parallel degree parameter + IF pParallelDegree < 1 OR pParallelDegree > 16 THEN + vgMsgTmp := ENV_MANAGER.MSG_INVALID_PARALLEL_DEGREE || ': ' || pParallelDegree || '. Valid range: 1-16'; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_INVALID_PARALLEL_DEGREE, vgMsgTmp); + END IF; + + -- Get partitions using shared function + vPartitions := GET_PARTITIONS(vSchemaName, vTableName, vKeyColumnName, pMinDate, pMaxDate, vParameters); + + ENV_MANAGER.LOG_PROCESS_EVENT('Found ' || vPartitions.COUNT || ' year/month combinations to export', 'INFO', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Date range: ' || TO_CHAR(pMinDate, 'YYYY-MM-DD HH24:MI:SS') || ' to ' || TO_CHAR(pMaxDate, 'YYYY-MM-DD HH24:MI:SS'), 'DEBUG', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('Parallel degree: ' || pParallelDegree, 'INFO', vParameters); + + -- Sequential processing (parallel degree = 1) + IF pParallelDegree = 1 THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Using sequential processing (pParallelDegree = 1)', 'DEBUG', vParameters); + + FOR i IN 1 .. vPartitions.COUNT LOOP + EXPORT_SINGLE_PARTITION( + pSchemaName => vSchemaName, + pTableName => vTableName, + pKeyColumnName => vKeyColumnName, + pYear => vPartitions(i).year, + pMonth => vPartitions(i).month, + pBucketUri => vBucketUri, + pFolderName => pFolderName, + pProcessedColumns => vProcessedColumnList, + pMinDate => pMinDate, + pMaxDate => pMaxDate, + pCredentialName => pCredentialName, + pFormat => 'CSV', + pFileBaseName => vFileBaseName, + pMaxFileSize => pMaxFileSize, + pParameters => vParameters + ); + END LOOP; + + -- Parallel processing (parallel degree > 1) + ELSE + -- Skip parallel processing if no partitions found + IF vPartitions.COUNT = 0 THEN + ENV_MANAGER.LOG_PROCESS_EVENT('No partitions to export - skipping parallel CSV processing', 'INFO', vParameters); + ELSE + DECLARE + vTaskName VARCHAR2(128) := 'DATA_CSV_EXPORT_TASK_' || TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISSFF'); + vChunkId NUMBER; + BEGIN + ENV_MANAGER.LOG_PROCESS_EVENT('Using parallel processing with ' || pParallelDegree || ' threads', 'INFO', vParameters); + + -- Clean up old completed chunks (>24 hours) to prevent table bloat + -- CRITICAL: Do NOT delete chunks from other active sessions (same-day tasks) + -- This prevents race conditions when multiple CSV exports run simultaneously + DELETE FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS + WHERE STATUS = 'COMPLETED' + AND CREATED_DATE < SYSTIMESTAMP - INTERVAL '1' DAY; + COMMIT; + + ENV_MANAGER.LOG_PROCESS_EVENT('Cleared old COMPLETED chunks (>24h). Active session chunks preserved.', 'DEBUG', vParameters); + + -- Populate chunks table (insert new chunks, preserve FAILED chunks for retry) + FOR i IN 1 .. vPartitions.COUNT LOOP + MERGE INTO CT_MRDS.A_PARALLEL_EXPORT_CHUNKS t + USING (SELECT i AS chunk_id, vTaskName AS task_name, vPartitions(i).year AS yr, vPartitions(i).month AS mn FROM DUAL) s + ON (t.CHUNK_ID = s.chunk_id AND t.TASK_NAME = s.task_name) + WHEN NOT MATCHED THEN + INSERT (CHUNK_ID, TASK_NAME, YEAR_VALUE, MONTH_VALUE, SCHEMA_NAME, TABLE_NAME, KEY_COLUMN_NAME, + BUCKET_URI, FOLDER_NAME, PROCESSED_COLUMNS, MIN_DATE, MAX_DATE, + CREDENTIAL_NAME, FORMAT_TYPE, FILE_BASE_NAME, TEMPLATE_TABLE_NAME, MAX_FILE_SIZE, JOB_CLASS, STATUS) + VALUES (i, vTaskName, vPartitions(i).year, vPartitions(i).month, vSchemaName, vTableName, vKeyColumnName, + vBucketUri, pFolderName, vProcessedColumnList, pMinDate, pMaxDate, + pCredentialName, 'CSV', vFileBaseName, pTemplateTableName, pMaxFileSize, pJobClass, 'PENDING') + WHEN MATCHED THEN + -- Match found: chunk exists for SAME task (composite PK: TASK_NAME, CHUNK_ID) + -- This handles retry scenario: reset FAILED chunks to PENDING for re-processing + UPDATE SET STATUS = CASE WHEN t.STATUS = 'FAILED' THEN 'PENDING' ELSE t.STATUS END, + ERROR_MESSAGE = CASE WHEN t.STATUS = 'FAILED' THEN NULL ELSE t.ERROR_MESSAGE END; + END LOOP; + COMMIT; + + -- Log chunk statistics (session-safe: only count chunks for THIS task) + DECLARE + vPendingCount NUMBER; + vFailedCount NUMBER; + BEGIN + SELECT COUNT(*) INTO vPendingCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'PENDING' AND TASK_NAME = vTaskName; + SELECT COUNT(*) INTO vFailedCount FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE STATUS = 'FAILED' AND TASK_NAME = vTaskName; + + ENV_MANAGER.LOG_PROCESS_EVENT('Chunk statistics for task ' || vTaskName || ': PENDING=' || vPendingCount || ', FAILED (retry)=' || vFailedCount, 'INFO', vParameters); + END; + + -- Create parallel task + DBMS_PARALLEL_EXECUTE.CREATE_TASK(task_name => vTaskName); + + -- Define chunks using SQL query to ensure TASK_NAME isolation + -- CRITICAL: Filter by TASK_NAME to avoid selecting chunks from other concurrent sessions + -- CRITICAL: Use START_ID and END_ID aliases to avoid ORA-00960 ambiguous column naming + DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_SQL( + task_name => vTaskName, + sql_stmt => 'SELECT CHUNK_ID AS START_ID, CHUNK_ID AS END_ID FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE TASK_NAME = ''' || vTaskName || ''' ORDER BY CHUNK_ID', + by_rowid => FALSE + ); + + -- Execute task in parallel + ENV_MANAGER.LOG_PROCESS_EVENT('Executing parallel CSV export task: ' || vTaskName || CASE WHEN pJobClass IS NOT NULL THEN ' with job class: ' || pJobClass ELSE '' END, 'DEBUG', vParameters); + + IF pJobClass IS NOT NULL THEN + DBMS_PARALLEL_EXECUTE.RUN_TASK( + task_name => vTaskName, + sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id, ''' || vTaskName || '''); END;', + language_flag => DBMS_SQL.NATIVE, + parallel_level => pParallelDegree, + job_class => pJobClass + ); + ELSE + DBMS_PARALLEL_EXECUTE.RUN_TASK( + task_name => vTaskName, + sql_stmt => 'BEGIN CT_MRDS.DATA_EXPORTER.EXPORT_PARTITION_PARALLEL(:start_id, :end_id, ''' || vTaskName || '''); END;', + language_flag => DBMS_SQL.NATIVE, + parallel_level => pParallelDegree + ); + END IF; + + -- Check for errors + DECLARE + vErrorCount NUMBER; + BEGIN + SELECT COUNT(*) INTO vErrorCount + FROM USER_PARALLEL_EXECUTE_CHUNKS + WHERE task_name = vTaskName AND status = 'PROCESSED_WITH_ERROR'; + + IF vErrorCount > 0 THEN + vgMsgTmp := 'Parallel CSV export completed with ' || vErrorCount || ' errors. Check USER_PARALLEL_EXECUTE_CHUNKS for details.'; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_PARALLEL_EXECUTION_FAILED, vgMsgTmp); + END IF; + END; + + -- Clean up task + DBMS_PARALLEL_EXECUTE.DROP_TASK(task_name => vTaskName); + + -- Clean up chunks for THIS specific task only (session-safe) + -- CRITICAL: Use TASK_NAME filter to avoid deleting chunks from other active CSV sessions + DELETE FROM CT_MRDS.A_PARALLEL_EXPORT_CHUNKS WHERE TASK_NAME = vTaskName; + COMMIT; + + ENV_MANAGER.LOG_PROCESS_EVENT('Parallel CSV execution completed successfully', 'INFO', vParameters); + EXCEPTION + WHEN OTHERS THEN + -- Attempt to drop task on error + BEGIN + DBMS_PARALLEL_EXECUTE.DROP_TASK(task_name => vTaskName); + EXCEPTION + WHEN OTHERS THEN NULL; -- Ignore drop errors + END; + + vgMsgTmp := ENV_MANAGER.MSG_PARALLEL_EXECUTION_FAILED || ': ' || SQLERRM || cgBL || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_PARALLEL_EXECUTION_FAILED, vgMsgTmp); + END; + END IF; + END IF; + + -- Note: File registration handled by EXPORT_SINGLE_PARTITION when pRegisterExport=TRUE + -- Each partition calls pRegisterExport logic independently during serial/parallel execution + + -- Register exported files to A_SOURCE_FILE_RECEIVED if requested (after successful export) + IF pRegisterExport THEN + -- Lookup A_SOURCE_FILE_CONFIG_KEY based on pFolderName parsing + -- Format: {BUCKET_AREA}/{SOURCE_KEY}/{TABLE_ID} + -- Example: 'ODS/CSDB/CSDB_DEBT_DAILY' -> SOURCE_KEY='CSDB', TABLE_ID='CSDB_DEBT_DAILY' + + -- Parse pFolderName to extract SOURCE_KEY and TABLE_ID + vSlashPos1 := INSTR(pFolderName, '/', 1, 1); -- First '/' position + vSlashPos2 := INSTR(pFolderName, '/', 1, 2); -- Second '/' position + + IF vSlashPos1 > 0 AND vSlashPos2 > 0 THEN + -- Extract segment 2 (SOURCE_KEY) and segment 3 (TABLE_ID) + vSourceKey := SUBSTR(pFolderName, vSlashPos1 + 1, vSlashPos2 - vSlashPos1 - 1); + vTableId := SUBSTR(pFolderName, vSlashPos2 + 1); + + -- Find configuration based on SOURCE_KEY and TABLE_ID + BEGIN + SELECT A_SOURCE_FILE_CONFIG_KEY + INTO vConfigKey + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE A_SOURCE_KEY = vSourceKey + AND TABLE_ID = vTableId + AND SOURCE_FILE_TYPE = 'INPUT' + AND ROWNUM = 1; + + ENV_MANAGER.LOG_PROCESS_EVENT('Found config key: ' || vConfigKey || ' for SOURCE=' || vSourceKey || ', TABLE=' || vTableId, 'DEBUG', vParameters); + EXCEPTION + WHEN NO_DATA_FOUND THEN + vConfigKey := -1; + ENV_MANAGER.LOG_PROCESS_EVENT('No config found for SOURCE=' || vSourceKey || ', TABLE=' || vTableId || ' - using default (-1)', 'INFO', vParameters); + END; + ELSE + -- Cannot parse folder name - use default + vConfigKey := -1; + ENV_MANAGER.LOG_PROCESS_EVENT('Cannot parse pFolderName: ' || pFolderName || ' - using default (-1)', 'WARNING', vParameters); + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('Registering ' || vPartitions.COUNT || ' exported files to A_SOURCE_FILE_RECEIVED with config key: ' || vConfigKey, 'INFO', vParameters); + + FOR i IN 1 .. vPartitions.COUNT LOOP + -- Construct filename and URI for this partition + vFileName := NVL(vFileBaseName, UPPER(REPLACE(vTableName, vSchemaName || '.', ''))) || '_' || vPartitions(i).year || vPartitions(i).month || '.csv'; + vFileUri := vBucketUri || CASE WHEN pFolderName IS NOT NULL THEN pFolderName || '/' ELSE '' END || sanitizeFilename(vFileName); + + -- Get file metadata from OCI bucket (CHECKSUM, CREATED, BYTES) with retry logic + DECLARE + vChecksum VARCHAR2(128); + vCreated TIMESTAMP WITH TIME ZONE; + vBytes NUMBER; + vActualFileName VARCHAR2(1000); -- Actual filename with Oracle suffix + vSanitizedFileName VARCHAR2(1000); + vRetryCount NUMBER := 0; + vMaxRetries NUMBER := 1; -- One retry after initial attempt + vRetryDelay NUMBER := 2; -- 2 seconds delay + BEGIN + -- Sanitize filename first (PL/SQL function cannot be used directly in SQL) + vSanitizedFileName := sanitizeFilename(vFileName); + + -- Remove .csv extension for LIKE pattern matching (Oracle adds suffixes BEFORE .csv) + -- Example: LEGACY_DEBT_202508.csv becomes LEGACY_DEBT_202508_1_20260211T102621591769Z.csv + vSanitizedFileName := REGEXP_REPLACE(vSanitizedFileName, '\.csv$', '', 1, 0, 'i'); + + -- Try to get file metadata with retry logic + <> + LOOP + BEGIN + SELECT object_name, checksum, created, bytes + INTO vActualFileName, vChecksum, vCreated, vBytes + FROM TABLE(DBMS_CLOUD.LIST_OBJECTS( + credential_name => pCredentialName, + location_uri => vBucketUri + )) + WHERE object_name LIKE CASE WHEN pFolderName IS NOT NULL THEN pFolderName || '/' ELSE '' END || vSanitizedFileName || '%' + ORDER BY created DESC, bytes DESC + FETCH FIRST 1 ROW ONLY; + + -- Extract filename only from full path (remove bucket folder prefix) + -- vActualFileName contains: 'ODS/CSDB/CSDB_DEBT/LEGACY_DEBT_202508_1_20260211T111341375171Z.csv' + -- Extract only: 'LEGACY_DEBT_202508_1_20260211T111341375171Z.csv' + vActualFileName := SUBSTR(vActualFileName, INSTR(vActualFileName, '/', -1) + 1); + + -- Success - exit retry loop + EXIT metadata_retry_loop; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + vRetryCount := vRetryCount + 1; + + IF vRetryCount <= vMaxRetries THEN + -- Log retry attempt + ENV_MANAGER.LOG_PROCESS_EVENT('File not found in bucket (attempt ' || vRetryCount || '/' || (vMaxRetries + 1) || '), retrying after ' || vRetryDelay || ' seconds: ' || vFileName, 'DEBUG', vParameters); + + -- Wait before retry using DBMS_SESSION.SLEEP (alternative to DBMS_LOCK) + DBMS_SESSION.SLEEP(vRetryDelay); + ELSE + -- Max retries exceeded - re-raise exception + RAISE; + END IF; + END; + END LOOP metadata_retry_loop; + + -- Create A_SOURCE_FILE_RECEIVED record for this export with metadata + vSourceFileReceivedKey := CT_MRDS.A_SOURCE_FILE_RECEIVED_KEY_SEQ.NEXTVAL; + INSERT INTO CT_MRDS.A_SOURCE_FILE_RECEIVED ( + A_SOURCE_FILE_RECEIVED_KEY, + A_SOURCE_FILE_CONFIG_KEY, + SOURCE_FILE_NAME, + CHECKSUM, + CREATED, + BYTES, + RECEPTION_DATE, + PROCESSING_STATUS, + PARTITION_YEAR, + PARTITION_MONTH, + ARCH_PATH, + PROCESS_NAME + ) VALUES ( + vSourceFileReceivedKey, + vConfigKey, -- Config key from A_SOURCE_FILE_CONFIG lookup + vActualFileName, -- Use actual filename with Oracle suffix + vChecksum, + vCreated, + vBytes, + SYSDATE, + 'INGESTED', + NULL, -- PARTITION_YEAR not used for CSV exports + NULL, -- PARTITION_MONTH not used for CSV exports + NULL, -- ARCH_PATH not used for CSV exports + pProcessName -- Process name from parameter + ); + + ENV_MANAGER.LOG_PROCESS_EVENT('Registered file: FileReceivedKey=' || vSourceFileReceivedKey || ', File=' || vActualFileName || ', Size=' || vBytes || ' bytes', 'DEBUG', vParameters); + EXCEPTION + WHEN NO_DATA_FOUND THEN + -- File not found after retries - log warning and continue without metadata + ENV_MANAGER.LOG_PROCESS_EVENT('WARNING: File not found in bucket after ' || (vMaxRetries + 1) || ' attempts: ' || vFileName, 'WARNING', vParameters); + + -- Sanitize filename for fallback INSERT (function cannot be used in SQL) + vSanitizedFileName := sanitizeFilename(vFileName); + + -- Insert without metadata + vSourceFileReceivedKey := CT_MRDS.A_SOURCE_FILE_RECEIVED_KEY_SEQ.NEXTVAL; + INSERT INTO CT_MRDS.A_SOURCE_FILE_RECEIVED ( + A_SOURCE_FILE_RECEIVED_KEY, + A_SOURCE_FILE_CONFIG_KEY, + SOURCE_FILE_NAME, + RECEPTION_DATE, + PROCESSING_STATUS, + PARTITION_YEAR, + PARTITION_MONTH, + ARCH_PATH, + PROCESS_NAME + ) VALUES ( + vSourceFileReceivedKey, + vConfigKey, -- Config key from A_SOURCE_FILE_CONFIG lookup + vSanitizedFileName, -- Fallback: use theoretical filename if actual not found + SYSDATE, + 'INGESTED', + NULL, -- PARTITION_YEAR not used for CSV exports + NULL, -- PARTITION_MONTH not used for CSV exports + NULL, -- ARCH_PATH not used for CSV exports + pProcessName -- Process name from parameter + ); + END; + END LOOP; + + COMMIT; + ENV_MANAGER.LOG_PROCESS_EVENT('Successfully registered all ' || vPartitions.COUNT || ' files', 'INFO', vParameters); + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('Export completed successfully for ' || vPartitions.COUNT || ' files', 'INFO', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + + EXCEPTION + WHEN ENV_MANAGER.ERR_TABLE_NOT_EXISTS THEN + vgMsgTmp := ENV_MANAGER.MSG_TABLE_NOT_EXISTS ||': '||vTableName; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_TABLE_NOT_EXISTS, vgMsgTmp); + WHEN ENV_MANAGER.ERR_COLUMN_NOT_EXISTS THEN + vgMsgTmp := ENV_MANAGER.MSG_COLUMN_NOT_EXISTS || ' (TableName.ColumnName): ' || vTableName||'.'||vKeyColumnName||CASE WHEN vCurrentCol IS NOT NULL THEN '.'||vCurrentCol||' in pColumnList' ELSE '' END; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_COLUMN_NOT_EXISTS, vgMsgTmp); + WHEN ENV_MANAGER.ERR_INVALID_PARALLEL_DEGREE THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_INVALID_PARALLEL_DEGREE, vgMsgTmp); + WHEN ENV_MANAGER.ERR_PARALLEL_EXECUTION_FAILED THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_PARALLEL_EXECUTION_FAILED, vgMsgTmp); + WHEN OTHERS THEN + -- Log complete error details including full stack trace and backtrace + ENV_MANAGER.LOG_PROCESS_ERROR('Export failed: ' || SQLERRM, vParameters, 'DATA_EXPORTER'); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + + END EXPORT_TABLE_DATA_TO_CSV_BY_DATE; + + ---------------------------------------------------------------------------------------------------- + -- VERSION MANAGEMENT FUNCTIONS + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_VERSION RETURN VARCHAR2 IS + BEGIN + RETURN PACKAGE_VERSION; + END GET_VERSION; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_BUILD_INFO RETURN VARCHAR2 IS + BEGIN + RETURN ENV_MANAGER.GET_PACKAGE_VERSION_INFO( + pPackageName => 'DATA_EXPORTER', + pVersion => PACKAGE_VERSION, + pBuildDate => PACKAGE_BUILD_DATE, + pAuthor => PACKAGE_AUTHOR + ); + END GET_BUILD_INFO; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2 IS + BEGIN + RETURN ENV_MANAGER.FORMAT_VERSION_HISTORY( + pPackageName => 'DATA_EXPORTER', + pVersionHistory => VERSION_HISTORY + ); + END GET_VERSION_HISTORY; + + ---------------------------------------------------------------------------------------------------- + +END; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DBMS_REGISTRY_SYS.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DBMS_REGISTRY_SYS.sql new file mode 100644 index 0000000..9dab0c3 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DBMS_REGISTRY_SYS.sql @@ -0,0 +1,5 @@ +-------------------------------------------------------- +-- DDL for Synonymn DBMS_REGISTRY_SYS +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE SYNONYM "PDBADMIN"."DBMS_REGISTRY_SYS" FOR "SYS"."DBMS_REGISTRY_SYS"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DRARIDMC.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DRARIDMC.sql new file mode 100644 index 0000000..778da74 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/DRARIDMC.sql @@ -0,0 +1,7 @@ +-------------------------------------------------------- +-- DDL for DB Link DRARIDMC +-------------------------------------------------------- + + CREATE DATABASE LINK "DRARIDMC" + CONNECT WITH "PDBADMIN"."DBLINK_CREDENTIAL" + USING '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST="PE-lzprd-mrds-tst-draridmc.adb.eu-frankfurt-1.oraclecloud.com")(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=g9e081ddad95b2d_draridmc_high.adb.oraclecloud.com))(SECURITY=(MY_WALLET_DIRECTORY="/u02/app/oracle/wallets/ssl_wallet")(SSL_SERVER_DN_MATCH=FALSE)))'; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ENV_MANAGER.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ENV_MANAGER.sql new file mode 100644 index 0000000..ef76087 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ENV_MANAGER.sql @@ -0,0 +1,630 @@ +-------------------------------------------------------- +-- DDL for Package ENV_MANAGER +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE PACKAGE "CT_MRDS"."ENV_MANAGER" +AUTHID CURRENT_USER +AS + /** + * General comment for package: Please put comments for functions and procedures as shown in below example. + * It is a standard. + * The structure of comment is used by GET_PACKAGE_DOCUMENTATION function + * which returns documentation text for confluence page (to Copy-Paste it). + **/ + + -- Example comment: + /** + * @name EX_PROCEDURE_NAME + * @desc Procedure description + * @example select ENV_MANAGER.EX_PROCEDURE_NAME(pParameter => 129) from dual; + * @ex_rslt Example Result + **/ + + -- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH) + PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.2.0'; + PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-12-20 10:00:00'; + PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski'; + + -- Version History (Latest changes first) + VERSION_HISTORY CONSTANT VARCHAR2(4000) := + '3.2.0 (2025-12-20): Added error codes for parallel execution support (CODE_INVALID_PARALLEL_DEGREE -20110, CODE_PARALLEL_EXECUTION_FAILED -20111)' || CHR(13)||CHR(10) || + '3.1.0 (2025-10-22): Added package hash tracking and automatic change detection system (SHA256 hashing)' || CHR(13)||CHR(10) || + '3.0.0 (2025-10-22): Added package versioning system with centralized version management functions' || CHR(13)||CHR(10) || + '2.1.0 (2025-10-15): Added ANALYZE_VALIDATION_ERRORS function for comprehensive CSV validation analysis' || CHR(13)||CHR(10) || + '2.0.0 (2025-10-01): Added LOG_PROCESS_ERROR procedure with enhanced error diagnostics and stack traces' || CHR(13)||CHR(10) || + '1.5.0 (2025-09-20): Added console logging support with gvConsoleLoggingEnabled configuration' || CHR(13)||CHR(10) || + '1.0.0 (2025-09-01): Initial release with error management and configuration system'; + + TYPE Error_Record IS RECORD ( + code PLS_INTEGER, + message VARCHAR2(4000) + ); + + TYPE tErrorList IS TABLE OF Error_Record INDEX BY PLS_INTEGER; + + Errors tErrorList; + + + guid VARCHAR2(32); + gvEnv VARCHAR2(200); + gvUsername VARCHAR2(128); + gvOsuser VARCHAR2(128); + gvMachine VARCHAR2(64); + gvModule VARCHAR2(64); + + gvNameSpace VARCHAR2(200); + gvRegion VARCHAR2(200); + gvDataBucketName VARCHAR2(200); + gvInboxBucketName VARCHAR2(200); + gvArchiveBucketName VARCHAR2(200); + gvDataBucketUri VARCHAR2(200); + gvInboxBucketUri VARCHAR2(200); + gvArchiveBucketUri VARCHAR2(200); + gvCredentialName VARCHAR2(200); + + -- Overwritten by variable "LoggingEnabled" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table + gvLoggingEnabled VARCHAR2(3) := 'ON'; -- 'ON' or 'OFF' + + -- Overwritten by variable "MinLogLevel" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table + -- Possible values: DEBUG ,INFO ,WARNING ,ERROR + gvMinLogLevel VARCHAR2(10) := 'DEBUG'; + + -- Overwritten by variable "DefaultDateFormat" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table + gvDefaultDateFormat VARCHAR2(200) := 'DD/MM/YYYY HH24:MI:SS'; + + -- Overwritten by variable "ConsoleLoggingEnabled" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table + gvConsoleLoggingEnabled VARCHAR2(3) := 'ON'; -- 'ON' or 'OFF' + + cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10); + + vgSourceFileConfigKey PLS_INTEGER; + + vgMsgTmp VARCHAR2(32000); + --Exceptions + ERR_EMPTY_FILEURI_AND_RECKEY EXCEPTION; + CODE_EMPTY_FILEURI_AND_RECKEY CONSTANT PLS_INTEGER := -20001; + MSG_EMPTY_FILEURI_AND_RECKEY VARCHAR2(4000) := 'Either pFileUri or pSourceFileReceivedKey must be not null'; + PRAGMA EXCEPTION_INIT( ERR_EMPTY_FILEURI_AND_RECKEY + ,CODE_EMPTY_FILEURI_AND_RECKEY); + + + ERR_NO_CONFIG_MATCH_FOR_FILEURI EXCEPTION; + CODE_NO_CONFIG_MATCH_FOR_FILEURI CONSTANT PLS_INTEGER := -20002; + MSG_NO_CONFIG_MATCH_FOR_FILEURI VARCHAR2(4000) := 'No match for source file in A_SOURCE_FILE_CONFIG table' + ||cgBL||' The file provided in parameter: pFileUri does not have ' + ||cgBL||' coresponding configuration in A_SOURCE_FILE_CONFIG table'; + PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_MATCH_FOR_FILEURI + ,CODE_NO_CONFIG_MATCH_FOR_FILEURI); + + ERR_MULTIPLE_MATCH_FOR_SRCFILE EXCEPTION; + CODE_MULTIPLE_MATCH_FOR_SRCFILE CONSTANT PLS_INTEGER := -20003; + MSG_MULTIPLE_MATCH_FOR_SRCFILE VARCHAR2(4000) := 'Multiple match for source file in A_SOURCE_FILE_CONFIG table'; + PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_MATCH_FOR_SRCFILE + ,CODE_MULTIPLE_MATCH_FOR_SRCFILE); + + ERR_MISSING_COLUMN_DATE_FORMAT EXCEPTION; + CODE_MISSING_COLUMN_DATE_FORMAT CONSTANT PLS_INTEGER := -20004; + MSG_MISSING_COLUMN_DATE_FORMAT VARCHAR2(4000) := 'Missing entry in config table: A_COLUMN_DATE_FORMAT primary key(TEMPLATE_TABLE_NAME, COLUMN_NAME)' + ||cgBL||' Remember: each column which data_type IN (''DATE'', ''TIMESTAMP'')' + ||cgBL||' should have DateFormat specified in A_COLUMN_DATE_FORMAT table ' + ||cgBL||' for example: ''YYYY-MM-DD'''; + PRAGMA EXCEPTION_INIT( ERR_MISSING_COLUMN_DATE_FORMAT + ,CODE_MISSING_COLUMN_DATE_FORMAT); + + ERR_MULTIPLE_COLUMN_DATE_FORMAT EXCEPTION; + CODE_MULTIPLE_COLUMN_DATE_FORMAT CONSTANT PLS_INTEGER := -20005; + MSG_MULTIPLE_COLUMN_DATE_FORMAT VARCHAR2(4000) := 'Multiple records for date format in A_COLUMN_DATE_FORMAT table' + ||cgBL||' There should be only one format specified for each DAT/TIMESTAMP column'; + PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_COLUMN_DATE_FORMAT + ,CODE_MULTIPLE_COLUMN_DATE_FORMAT); + + + ERR_DIDNT_GET_LOAD_OPERATION_ID EXCEPTION; + CODE_DIDNT_GET_LOAD_OPERATION_ID CONSTANT PLS_INTEGER := -20006; + MSG_DIDNT_GET_LOAD_OPERATION_ID VARCHAR2(4000) := 'Didnt get load operation id from external table validation'; + PRAGMA EXCEPTION_INIT( ERR_DIDNT_GET_LOAD_OPERATION_ID + ,CODE_DIDNT_GET_LOAD_OPERATION_ID); + + ERR_NO_CONFIG_FOR_RECEIVED_FILE EXCEPTION; + CODE_NO_CONFIG_FOR_RECEIVED_FILE CONSTANT PLS_INTEGER := -20007; + MSG_NO_CONFIG_FOR_RECEIVED_FILE VARCHAR2(4000) := 'No match for received source file in A_SOURCE_FILE_CONFIG ' + ||cgBL||' or missing data in A_SOURCE_FILE_RECEIVED table for provided pSourceFileReceivedKey parameter'; + PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_FOR_RECEIVED_FILE + ,CODE_NO_CONFIG_FOR_RECEIVED_FILE); + + ERR_MULTI_CONFIG_FOR_RECEIVED_FILE EXCEPTION; + CODE_MULTI_CONFIG_FOR_RECEIVED_FILE CONSTANT PLS_INTEGER := -20008; + MSG_MULTI_CONFIG_FOR_RECEIVED_FILE VARCHAR2(4000) := 'Multiple matchs for received source file in A_SOURCE_FILE_CONFIG'; + PRAGMA EXCEPTION_INIT( ERR_MULTI_CONFIG_FOR_RECEIVED_FILE + ,CODE_MULTI_CONFIG_FOR_RECEIVED_FILE); + + ERR_FILE_NOT_FOUND_ON_CLOUD EXCEPTION; + CODE_FILE_NOT_FOUND_ON_CLOUD CONSTANT PLS_INTEGER := -20009; + MSG_FILE_NOT_FOUND_ON_CLOUD VARCHAR2(4000) := 'File not found on the cloud'; + PRAGMA EXCEPTION_INIT( ERR_FILE_NOT_FOUND_ON_CLOUD + ,CODE_FILE_NOT_FOUND_ON_CLOUD); + + ERR_FILE_VALIDATION_FAILED EXCEPTION; + CODE_FILE_VALIDATION_FAILED CONSTANT PLS_INTEGER := -20010; + MSG_FILE_VALIDATION_FAILED VARCHAR2(4000) := 'File validation failed'; + PRAGMA EXCEPTION_INIT( ERR_FILE_VALIDATION_FAILED + ,CODE_FILE_VALIDATION_FAILED); + + ERR_EXCESS_COLUMNS_DETECTED EXCEPTION; + CODE_EXCESS_COLUMNS_DETECTED CONSTANT PLS_INTEGER := -20011; + MSG_EXCESS_COLUMNS_DETECTED VARCHAR2(4000) := 'CSV file contains more columns than template allows'; + PRAGMA EXCEPTION_INIT( ERR_EXCESS_COLUMNS_DETECTED + ,CODE_EXCESS_COLUMNS_DETECTED); + + ERR_NO_CONFIG_MATCH EXCEPTION; + CODE_NO_CONFIG_MATCH CONSTANT PLS_INTEGER := -20012; + MSG_NO_CONFIG_MATCH VARCHAR2(4000) := 'No match for specified parameters in A_SOURCE_FILE_CONFIG table'; + PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_MATCH + ,CODE_NO_CONFIG_MATCH); + + ERR_UNKNOWN_PREFIX EXCEPTION; + CODE_UNKNOWN_PREFIX CONSTANT PLS_INTEGER := -20013; + MSG_UNKNOWN_PREFIX VARCHAR2(4000) := 'Unknown prefix'; + PRAGMA EXCEPTION_INIT( ERR_UNKNOWN_PREFIX + ,CODE_UNKNOWN_PREFIX); + + ERR_TABLE_NOT_EXISTS EXCEPTION; + CODE_TABLE_NOT_EXISTS CONSTANT PLS_INTEGER := -20014; + MSG_TABLE_NOT_EXISTS VARCHAR2(4000) := 'Table does not exist'; + PRAGMA EXCEPTION_INIT( ERR_TABLE_NOT_EXISTS + ,CODE_TABLE_NOT_EXISTS); + + ERR_COLUMN_NOT_EXISTS EXCEPTION; + CODE_COLUMN_NOT_EXISTS CONSTANT PLS_INTEGER := -20015; + MSG_COLUMN_NOT_EXISTS VARCHAR2(4000) := 'Column does not exist in table'; + PRAGMA EXCEPTION_INIT( ERR_COLUMN_NOT_EXISTS + ,CODE_COLUMN_NOT_EXISTS); + + ERR_UNSUPPORTED_DATA_TYPE EXCEPTION; + CODE_UNSUPPORTED_DATA_TYPE CONSTANT PLS_INTEGER := -20016; + MSG_UNSUPPORTED_DATA_TYPE VARCHAR2(4000) := 'Unsupported data type'; + PRAGMA EXCEPTION_INIT( ERR_UNSUPPORTED_DATA_TYPE + ,CODE_UNSUPPORTED_DATA_TYPE); + + ERR_MISSING_SOURCE_KEY EXCEPTION; + CODE_MISSING_SOURCE_KEY CONSTANT PLS_INTEGER := -20017; + MSG_MISSING_SOURCE_KEY VARCHAR2(4000) := 'The Source was not found in parent table A_SOURCE'; + PRAGMA EXCEPTION_INIT( ERR_MISSING_SOURCE_KEY + ,CODE_MISSING_SOURCE_KEY); + + ERR_NULL_SOURCE_FILE_CONFIG_KEY EXCEPTION; + CODE_NULL_SOURCE_FILE_CONFIG_KEY CONSTANT PLS_INTEGER := -20018; + MSG_NULL_SOURCE_FILE_CONFIG_KEY VARCHAR2(4000) := 'No entry in A_SOURCE_FILE_CONFIG table for specified A_SOURCE_FILE_CONFIG_KEY'; + PRAGMA EXCEPTION_INIT( ERR_NULL_SOURCE_FILE_CONFIG_KEY + ,CODE_NULL_SOURCE_FILE_CONFIG_KEY); + + ERR_DUPLICATED_SOURCE_KEY EXCEPTION; + CODE_DUPLICATED_SOURCE_KEY CONSTANT PLS_INTEGER := -20019; + MSG_DUPLICATED_SOURCE_KEY VARCHAR2(4000) := 'The Source already exists in the A_SOURCE table'; + PRAGMA EXCEPTION_INIT( ERR_DUPLICATED_SOURCE_KEY + ,CODE_DUPLICATED_SOURCE_KEY); + + ERR_MISSING_CONTAINER_CONFIG EXCEPTION; + CODE_MISSING_CONTAINER_CONFIG CONSTANT PLS_INTEGER := -20020; + MSG_MISSING_CONTAINER_CONFIG VARCHAR2(4000) := 'No match in A_SOURCE_FILE_CONFIG table where SOURCE_FILE_TYPE=''CONTAINER'' and specified SOURCE_FILE_ID'; + PRAGMA EXCEPTION_INIT( ERR_MISSING_CONTAINER_CONFIG + ,CODE_MISSING_CONTAINER_CONFIG); + + ERR_MULTIPLE_CONTAINER_ENTRIES EXCEPTION; + CODE_MULTIPLE_CONTAINER_ENTRIES CONSTANT PLS_INTEGER := -20021; + MSG_MULTIPLE_CONTAINER_ENTRIES VARCHAR2(4000) := 'Multiple matches in A_SOURCE_FILE_CONFIG table where SOURCE_FILE_TYPE=''CONTAINER'' and specified SOURCE_FILE_ID'; + PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_CONTAINER_ENTRIES + ,CODE_MULTIPLE_CONTAINER_ENTRIES); + + ERR_WRONG_DESTINATION_PARAM EXCEPTION; + CODE_WRONG_DESTINATION_PARAM CONSTANT PLS_INTEGER := -20022; + MSG_WRONG_DESTINATION_PARAM VARCHAR2(4000) := 'Wrong destination parameter provided.'; + PRAGMA EXCEPTION_INIT( ERR_WRONG_DESTINATION_PARAM + ,CODE_WRONG_DESTINATION_PARAM); + + ERR_FILE_NOT_EXISTS_ON_CLOUD EXCEPTION; + CODE_FILE_NOT_EXISTS_ON_CLOUD CONSTANT PLS_INTEGER := -20023; + MSG_FILE_NOT_EXISTS_ON_CLOUD VARCHAR2(4000) := 'File not exists on cloud.'; + PRAGMA EXCEPTION_INIT( ERR_FILE_NOT_EXISTS_ON_CLOUD + ,CODE_FILE_NOT_EXISTS_ON_CLOUD); + + ERR_FILE_ALREADY_REGISTERED EXCEPTION; + CODE_FILE_ALREADY_REGISTERED CONSTANT PLS_INTEGER := -20024; + MSG_FILE_ALREADY_REGISTERED VARCHAR2(4000) := 'File already registered in A_SOURCE_FILE_RECEIVED table.'; + PRAGMA EXCEPTION_INIT( ERR_FILE_ALREADY_REGISTERED + ,CODE_FILE_ALREADY_REGISTERED); + + ERR_WRONG_DATE_TIMESTAMP_FORMAT EXCEPTION; + CODE_WRONG_DATE_TIMESTAMP_FORMAT CONSTANT PLS_INTEGER := -20025; + MSG_WRONG_DATE_TIMESTAMP_FORMAT VARCHAR2(4000) := 'Provided DATE or TIMESTAMP format has errors (possible duplicated codes, ex: ''DD'').'; + PRAGMA EXCEPTION_INIT( ERR_WRONG_DATE_TIMESTAMP_FORMAT + ,CODE_WRONG_DATE_TIMESTAMP_FORMAT); + + ERR_ENVIRONMENT_NOT_SET EXCEPTION; + CODE_ENVIRONMENT_NOT_SET CONSTANT PLS_INTEGER := -20026; + MSG_ENVIRONMENT_NOT_SET VARCHAR2(4000) := 'EnvironmentID not set' + ||cgBL||' Information about environment is needed to get proper configuration values.' + ||cgBL||' It can be set up in two different ways:' + ||cgBL||' 1. Set it on session level: execute DBMS_SESSION.SET_IDENTIFIER (client_id => ''dev'')' + ||cgBL||' 2. Set it on configuration level: Insert into CT_MRDS.A_FILE_MANAGER_CONFIG (ENVIRONMENT_ID,CONFIG_VARIABLE,CONFIG_VARIABLE_VALUE) values (''default'',''environment_id'',''dev'')' + ||cgBL||' Session level setup (1.) takes precedence over configuration level one (2.)' + ; + PRAGMA EXCEPTION_INIT( ERR_ENVIRONMENT_NOT_SET + ,CODE_ENVIRONMENT_NOT_SET); + + + ERR_CONFIG_VARIABLE_NOT_SET EXCEPTION; + CODE_CONFIG_VARIABLE_NOT_SET CONSTANT PLS_INTEGER := -20027; + MSG_CONFIG_VARIABLE_NOT_SET VARCHAR2(4000) := 'Missing configuration value in A_FILE_MANAGER_CONFIG'; + PRAGMA EXCEPTION_INIT( ERR_CONFIG_VARIABLE_NOT_SET + ,CODE_CONFIG_VARIABLE_NOT_SET); + + ERR_NOT_INPUT_SOURCE_FILE_TYPE EXCEPTION; + CODE_NOT_INPUT_SOURCE_FILE_TYPE CONSTANT PLS_INTEGER := -20028; + MSG_NOT_INPUT_SOURCE_FILE_TYPE VARCHAR2(4000) := 'Archival can be executed only for A_SOURCE_FILE_CONFIG_KEY where SOURCE_FILE_TYPE=''INPUT'''; + PRAGMA EXCEPTION_INIT( ERR_NOT_INPUT_SOURCE_FILE_TYPE + ,CODE_NOT_INPUT_SOURCE_FILE_TYPE); + + ERR_EXP_DATA_FOR_ARCH_FAILED EXCEPTION; + CODE_EXP_DATA_FOR_ARCH_FAILED CONSTANT PLS_INTEGER := -20029; + MSG_EXP_DATA_FOR_ARCH_FAILED VARCHAR2(4000) := 'Export data for archival failed.'; + PRAGMA EXCEPTION_INIT( ERR_EXP_DATA_FOR_ARCH_FAILED + ,CODE_EXP_DATA_FOR_ARCH_FAILED); + + ERR_RESTORE_FILE_FROM_TRASH EXCEPTION; + CODE_RESTORE_FILE_FROM_TRASH CONSTANT PLS_INTEGER := -20030; + MSG_RESTORE_FILE_FROM_TRASH VARCHAR2(4000) := 'Unexpected issues occured while archival process. Restoration of exported files failed.'; + PRAGMA EXCEPTION_INIT( ERR_RESTORE_FILE_FROM_TRASH + ,CODE_RESTORE_FILE_FROM_TRASH); + + ERR_CHANGE_STAT_TO_ARCHIVED_FAILED EXCEPTION; + CODE_CHANGE_STAT_TO_ARCHIVED_FAILED CONSTANT PLS_INTEGER := -20031; + MSG_CHANGE_STAT_TO_ARCHIVED_FAILED VARCHAR2(4000) := 'Failed to change file status to: ARCHIVED in A_SOURCE_FILE_RECEIVED table.'; + PRAGMA EXCEPTION_INIT( ERR_CHANGE_STAT_TO_ARCHIVED_FAILED + ,CODE_CHANGE_STAT_TO_ARCHIVED_FAILED); + + ERR_MOVE_FILE_TO_TRASH_FAILED EXCEPTION; + CODE_MOVE_FILE_TO_TRASH_FAILED CONSTANT PLS_INTEGER := -20032; + MSG_MOVE_FILE_TO_TRASH_FAILED VARCHAR2(4000) := 'FAILED to move file to TRASH before DROPPING it.'; + PRAGMA EXCEPTION_INIT( ERR_MOVE_FILE_TO_TRASH_FAILED + ,CODE_MOVE_FILE_TO_TRASH_FAILED); + + ERR_DROP_EXPORTED_FILES_FAILED EXCEPTION; + CODE_DROP_EXPORTED_FILES_FAILED CONSTANT PLS_INTEGER := -20033; + MSG_DROP_EXPORTED_FILES_FAILED VARCHAR2(4000) := 'FAILED to move file to TRASH before DROPPING it.'; + PRAGMA EXCEPTION_INIT( ERR_DROP_EXPORTED_FILES_FAILED + ,CODE_DROP_EXPORTED_FILES_FAILED); + + ERR_INVALID_BUCKET_AREA EXCEPTION; + CODE_INVALID_BUCKET_AREA CONSTANT PLS_INTEGER := -20034; + MSG_INVALID_BUCKET_AREA VARCHAR2(4000) := 'Invalid bucket area specified. Valid values: INBOX, ODS, DATA, ARCHIVE'; + PRAGMA EXCEPTION_INIT( ERR_INVALID_BUCKET_AREA + ,CODE_INVALID_BUCKET_AREA); + + ERR_INVALID_PARALLEL_DEGREE EXCEPTION; + CODE_INVALID_PARALLEL_DEGREE CONSTANT PLS_INTEGER := -20110; + MSG_INVALID_PARALLEL_DEGREE VARCHAR2(4000) := 'Invalid parallel degree parameter. Must be between 1 and 16'; + PRAGMA EXCEPTION_INIT( ERR_INVALID_PARALLEL_DEGREE + ,CODE_INVALID_PARALLEL_DEGREE); + + ERR_PARALLEL_EXECUTION_FAILED EXCEPTION; + CODE_PARALLEL_EXECUTION_FAILED CONSTANT PLS_INTEGER := -20111; + MSG_PARALLEL_EXECUTION_FAILED VARCHAR2(4000) := 'Parallel execution failed'; + PRAGMA EXCEPTION_INIT( ERR_PARALLEL_EXECUTION_FAILED + ,CODE_PARALLEL_EXECUTION_FAILED); + + ERR_UNKNOWN EXCEPTION; + CODE_UNKNOWN CONSTANT PLS_INTEGER := -20999; + MSG_UNKNOWN VARCHAR2(4000) := 'Unknown Error Occured'; + PRAGMA EXCEPTION_INIT( ERR_UNKNOWN + ,CODE_UNKNOWN); + + --------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------- + + + + + /** + * @name LOG_PROCESS_EVENT + * @desc Insert a new log record into A_PROCESS_LOG table. + * Also outputs to console if gvConsoleLoggingEnabled = 'ON'. + * Respects logging level configuration (gvMinLogLevel). + * @example ENV_MANAGER.LOG_PROCESS_EVENT('Process completed successfully', 'INFO', 'pParam1=value1'); + * @ex_rslt Record inserted into A_PROCESS_LOG table and optionally displayed in console output + **/ + PROCEDURE LOG_PROCESS_EVENT ( + pLogMessage VARCHAR2 + ,pLogLevel VARCHAR2 DEFAULT 'ERROR' + ,pParameters VARCHAR2 DEFAULT NULL + ,pProcessName VARCHAR2 DEFAULT 'FILE_MANAGER' + ); + + /** + * @name LOG_PROCESS_ERROR + * @desc Insert a detailed error record into A_PROCESS_LOG table with full stack trace, backtrace, and call stack. + * This procedure captures comprehensive error information for debugging purposes while + * allowing clean user-facing error messages to be raised separately. + * @param pLogMessage - Base error message description + * @param pParameters - Procedure parameters for context + * @param pProcessName - Name of the calling process/package + * @ex_rslt Record inserted into A_PROCESS_LOG table with complete error stack information + */ + PROCEDURE LOG_PROCESS_ERROR ( + pLogMessage VARCHAR2 + ,pParameters VARCHAR2 DEFAULT NULL + ,pProcessName VARCHAR2 DEFAULT 'FILE_MANAGER' + ); + + /** + * @name INIT_ERRORS + * @desc Loads data into Errors array. + * Errors array is a list of Record(Error_Code, Error_Message) index by Error_Code. + * Called automatically during package initialization. + * @example Called automatically when package is first referenced + * @ex_rslt Errors array populated with all error codes and messages + **/ + PROCEDURE INIT_ERRORS; + + + + /** + * @name GET_DEFAULT_ENV + * @desc It returns string with name of default environment. + * Return string is A_FILE_MANAGER_CONFIG.ENVIRONMENT_ID value. + * @example select ENV_MANAGER.GET_DEFAULT_ENV() from dual; + * @ex_rslt dev + **/ + FUNCTION GET_DEFAULT_ENV + RETURN VARCHAR2; + + + + /** + * @name INIT_VARIABLES + * @desc For specified pEnv parameter (A_FILE_MANAGER_CONFIG.ENVIRONMENT_ID) + * Assign values to following global package variables: + * - gvNameSpace + * - gvRegion + * - gvCredentialName + * - gvInboxBucketName + * - gvDataBucketName + * - gvArchiveBucketName + * - gvInboxBucketUri + * - gvDataBucketUri + * - gvArchiveBucketUri + * - gvLoggingEnabled + * - gvMinLogLevel + * - gvDefaultDateFormat + * - gvConsoleLoggingEnabled + **/ + PROCEDURE INIT_VARIABLES( + pEnv VARCHAR2 + ); + + + + /** + * @name GET_ERROR_MESSAGE + * @desc It returns string with error message for specified pCode (Error_Code). + * Error message is take from Errors Array loaded by INIT_ERRORS procedure + * @example select ENV_MANAGER.GET_ERROR_MESSAGE(pCode => -20009) from dual; + * @ex_rslt File not found on the cloud + **/ + FUNCTION GET_ERROR_MESSAGE( + pCode PLS_INTEGER + ) RETURN VARCHAR2; + + + + /** + * @name GET_ERROR_STACK + * @desc It returns string with all possible error stack info. + * Error message is take from Errors Array loaded by INIT_ERRORS procedure + * @example + * select ENV_MANAGER.GET_ERROR_STACK( + * pFormat => 'OUTPUT' + * ,pCode => -20009 + * ,pSourceFileReceivedKey => NULL) + * from dual + * @ex_rslt + * ------------------------------------------------------+ + * Error Message: + * ORA-0000: normal, successful completion + * ------------------------------------------------------- + * Error Stack: + * ------------------------------------------------------- + * Error Backtrace: + * ------------------------------------------------------+ + **/ + FUNCTION GET_ERROR_STACK( + pFormat VARCHAR2 + ,pCode PLS_INTEGER + ,pSourceFileReceivedKey CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL + ) RETURN VARCHAR2; + + /** + * @name FORMAT_PARAMETERS + * @desc Formats parameter list for logging purposes. + * Converts SYS.ODCIVARCHAR2LIST to formatted string with proper NULL handling. + * @example select ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('param1=value1', 'param2=NULL')) from dual; + * @ex_rslt param1=value1 , + * param2=NULL + **/ + FUNCTION FORMAT_PARAMETERS( + pParameterList SYS.ODCIVARCHAR2LIST + ) RETURN VARCHAR2; + + /** + * @name ANALYZE_VALIDATION_ERRORS + * @desc Analyzes CSV validation errors and generates detailed diagnostic report. + * Compares CSV structure with template table and provides specific error analysis. + * Includes suggested solutions for common validation issues. + * @param pValidationLogTable - Name of validation log table (e.g., VALIDATE$242_LOG) + * @param pTemplateSchema - Schema of template table (e.g., CT_ET_TEMPLATES) + * @param pTemplateTable - Name of template table (e.g., MOCK_PROC_TABLE) + * @param pCsvFileUri - URI of CSV file being validated + * @example SELECT ENV_MANAGER.ANALYZE_VALIDATION_ERRORS('VALIDATE$242_LOG', 'CT_ET_TEMPLATES', 'MOCK_PROC_TABLE', 'https://...') FROM DUAL; + * @ex_rslt Detailed validation analysis report with column mismatches and solutions + **/ + FUNCTION ANALYZE_VALIDATION_ERRORS( + pValidationLogTable VARCHAR2, + pTemplateSchema VARCHAR2, + pTemplateTable VARCHAR2, + pCsvFileUri VARCHAR2 + ) RETURN VARCHAR2; + + --------------------------------------------------------------------------------------------------------------------------- + -- PACKAGE VERSION MANAGEMENT FUNCTIONS + --------------------------------------------------------------------------------------------------------------------------- + + /** + * @name GET_VERSION + * @desc Returns the current version number of the ENV_MANAGER package. + * Uses semantic versioning format (MAJOR.MINOR.PATCH). + * @example SELECT ENV_MANAGER.GET_VERSION() FROM DUAL; + * @ex_rslt 3.0.0 + **/ + FUNCTION GET_VERSION RETURN VARCHAR2; + + /** + * @name GET_BUILD_INFO + * @desc Returns comprehensive build information including version, build date, and author. + * Formatted for display in logs or monitoring systems. + * @example SELECT ENV_MANAGER.GET_BUILD_INFO() FROM DUAL; + * @ex_rslt Package: ENV_MANAGER + * Version: 3.0.0 + * Build Date: 2025-10-22 16:00:00 + * Author: Grzegorz Michalski + **/ + FUNCTION GET_BUILD_INFO RETURN VARCHAR2; + + /** + * @name GET_VERSION_HISTORY + * @desc Returns complete version history with all releases and changes. + * Shows evolution of package features over time. + * @example SELECT ENV_MANAGER.GET_VERSION_HISTORY() FROM DUAL; + * @ex_rslt ENV_MANAGER Version History: + * 3.0.0 (2025-10-22): Added package versioning system... + * 2.1.0 (2025-10-15): Added ANALYZE_VALIDATION_ERRORS function... + **/ + FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2; + + /** + * @name GET_PACKAGE_VERSION_INFO + * @desc Universal function to get formatted version information for any package. + * This centralized function is used by all packages in the system. + * @param pPackageName - Name of the package + * @param pVersion - Version string (MAJOR.MINOR.PATCH format) + * @param pBuildDate - Build date timestamp + * @param pAuthor - Package author name + * @example SELECT ENV_MANAGER.GET_PACKAGE_VERSION_INFO('FILE_MANAGER', '2.1.0', '2025-10-22 15:00:00', 'Grzegorz Michalski') FROM DUAL; + * @ex_rslt Package: FILE_MANAGER + * Version: 2.1.0 + * Build Date: 2025-10-22 15:00:00 + * Author: Grzegorz Michalski + **/ + FUNCTION GET_PACKAGE_VERSION_INFO( + pPackageName VARCHAR2, + pVersion VARCHAR2, + pBuildDate VARCHAR2, + pAuthor VARCHAR2 + ) RETURN VARCHAR2; + + /** + * @name FORMAT_VERSION_HISTORY + * @desc Universal function to format version history for any package. + * Adds package name header and proper formatting. + * @param pPackageName - Name of the package + * @param pVersionHistory - Complete version history text + * @example SELECT ENV_MANAGER.FORMAT_VERSION_HISTORY('FILE_MANAGER', '2.1.0 (2025-10-22): Export procedures...') FROM DUAL; + * @ex_rslt FILE_MANAGER Version History: + * 2.1.0 (2025-10-22): Export procedures... + **/ + FUNCTION FORMAT_VERSION_HISTORY( + pPackageName VARCHAR2, + pVersionHistory VARCHAR2 + ) RETURN VARCHAR2; + + --------------------------------------------------------------------------------------------------------------------------- + -- PACKAGE HASH + CHANGE DETECTION FUNCTIONS + --------------------------------------------------------------------------------------------------------------------------- + + /** + * @name CALCULATE_PACKAGE_HASH + * @desc Calculates SHA256 hash of package source code from ALL_SOURCE. + * Returns hash for both SPEC and BODY (if exists). + * Used for automatic change detection. + * @param pPackageOwner - Schema owner of the package + * @param pPackageName - Name of the package + * @param pPackageType - Type of package code ('PACKAGE' for SPEC, 'PACKAGE BODY' for BODY) + * @example SELECT ENV_MANAGER.CALCULATE_PACKAGE_HASH('CT_MRDS', 'FILE_MANAGER', 'PACKAGE') FROM DUAL; + * @ex_rslt A7B3C5D9E8F1234567890ABCDEF... (64-character SHA256 hash) + **/ + FUNCTION CALCULATE_PACKAGE_HASH( + pPackageOwner VARCHAR2, + pPackageName VARCHAR2, + pPackageType VARCHAR2 -- 'PACKAGE' or 'PACKAGE BODY' + ) RETURN VARCHAR2; + + /** + * @name TRACK_PACKAGE_VERSION + * @desc Records package version and source code hash in A_PACKAGE_VERSION_TRACKING table. + * Automatically detects if source code changed without version update. + * Should be called after every package deployment. + * @param pPackageOwner - Schema owner of the package + * @param pPackageName - Name of the package + * @param pPackageVersion - Current version from PACKAGE_VERSION constant + * @param pPackageBuildDate - Build date from PACKAGE_BUILD_DATE constant + * @param pPackageAuthor - Author from PACKAGE_AUTHOR constant + * @example EXEC ENV_MANAGER.TRACK_PACKAGE_VERSION('CT_MRDS', 'FILE_MANAGER', '3.2.0', '2025-10-22 16:30:00', 'Grzegorz Michalski'); + * @ex_rslt Record inserted into A_PACKAGE_VERSION_TRACKING with change detection status + **/ + PROCEDURE TRACK_PACKAGE_VERSION( + pPackageOwner VARCHAR2, + pPackageName VARCHAR2, + pPackageVersion VARCHAR2, + pPackageBuildDate VARCHAR2, + pPackageAuthor VARCHAR2 + ); + + /** + * @name CHECK_PACKAGE_CHANGES + * @desc Checks if package source code has changed since last tracking. + * Compares current hash with last recorded hash in A_PACKAGE_VERSION_TRACKING. + * Returns detailed change detection report. + * @param pPackageOwner - Schema owner of the package + * @param pPackageName - Name of the package + * @example SELECT ENV_MANAGER.CHECK_PACKAGE_CHANGES('CT_MRDS', 'FILE_MANAGER') FROM DUAL; + * @ex_rslt WARNING: Package changed without version update! + * Last Version: 3.2.0 + * Current Hash (SPEC): A7B3C5D9... + * Last Hash (SPEC): B8C4D6E0... + * RECOMMENDATION: Update PACKAGE_VERSION and PACKAGE_BUILD_DATE + **/ + FUNCTION CHECK_PACKAGE_CHANGES( + pPackageOwner VARCHAR2, + pPackageName VARCHAR2 + ) RETURN VARCHAR2; + + /** + * @name GET_PACKAGE_HASH_INFO + * @desc Returns formatted information about package hash and tracking history. + * Includes current hash, last tracked hash, and change detection status. + * @param pPackageOwner - Schema owner of the package + * @param pPackageName - Name of the package + * @example SELECT ENV_MANAGER.GET_PACKAGE_HASH_INFO('CT_MRDS', 'FILE_MANAGER') FROM DUAL; + * @ex_rslt Package: CT_MRDS.FILE_MANAGER + * Current Version: 3.2.0 + * Current Hash (SPEC): A7B3C5D9... + * Last Tracked: 2025-10-22 16:30:00 + * Status: OK - No changes detected + **/ + FUNCTION GET_PACKAGE_HASH_INFO( + pPackageOwner VARCHAR2, + pPackageName VARCHAR2 + ) RETURN VARCHAR2; + +END ENV_MANAGER; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ENV_MANAGER_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ENV_MANAGER_1.sql new file mode 100644 index 0000000..b9f43fa --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ENV_MANAGER_1.sql @@ -0,0 +1,1173 @@ +-------------------------------------------------------- +-- DDL for Package Body ENV_MANAGER +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE PACKAGE BODY "CT_MRDS"."ENV_MANAGER" +AS + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE INIT_ERRORS IS + BEGIN + Errors(CODE_EMPTY_FILEURI_AND_RECKEY) := Error_Record(CODE_EMPTY_FILEURI_AND_RECKEY, MSG_EMPTY_FILEURI_AND_RECKEY); -- -20001 + Errors(CODE_NO_CONFIG_MATCH_FOR_FILEURI) := Error_Record(CODE_NO_CONFIG_MATCH_FOR_FILEURI, MSG_NO_CONFIG_MATCH_FOR_FILEURI); -- -20002 + Errors(CODE_MULTIPLE_MATCH_FOR_SRCFILE) := Error_Record(CODE_MULTIPLE_MATCH_FOR_SRCFILE, MSG_MULTIPLE_MATCH_FOR_SRCFILE); -- -20003 + Errors(CODE_MISSING_COLUMN_DATE_FORMAT) := Error_Record(CODE_MISSING_COLUMN_DATE_FORMAT, MSG_MISSING_COLUMN_DATE_FORMAT); -- -20004 + Errors(CODE_MULTIPLE_COLUMN_DATE_FORMAT) := Error_Record(CODE_MULTIPLE_COLUMN_DATE_FORMAT, MSG_MULTIPLE_COLUMN_DATE_FORMAT); -- -20005 + Errors(CODE_DIDNT_GET_LOAD_OPERATION_ID) := Error_Record(CODE_DIDNT_GET_LOAD_OPERATION_ID, MSG_DIDNT_GET_LOAD_OPERATION_ID); -- -20006 + Errors(CODE_NO_CONFIG_FOR_RECEIVED_FILE) := Error_Record(CODE_NO_CONFIG_FOR_RECEIVED_FILE, MSG_NO_CONFIG_FOR_RECEIVED_FILE); -- -20007 + Errors(CODE_MULTI_CONFIG_FOR_RECEIVED_FILE) := Error_Record(CODE_MULTI_CONFIG_FOR_RECEIVED_FILE, MSG_MULTI_CONFIG_FOR_RECEIVED_FILE); -- -20008 + Errors(CODE_FILE_NOT_FOUND_ON_CLOUD) := Error_Record(CODE_FILE_NOT_FOUND_ON_CLOUD, MSG_FILE_NOT_FOUND_ON_CLOUD); -- -20009 + Errors(CODE_FILE_VALIDATION_FAILED) := Error_Record(CODE_FILE_VALIDATION_FAILED, MSG_FILE_VALIDATION_FAILED); -- -20010 + Errors(CODE_EXCESS_COLUMNS_DETECTED) := Error_Record(CODE_EXCESS_COLUMNS_DETECTED, MSG_EXCESS_COLUMNS_DETECTED); -- -20011 + Errors(CODE_NO_CONFIG_MATCH) := Error_Record(CODE_NO_CONFIG_MATCH, MSG_NO_CONFIG_MATCH); -- -20012 + Errors(CODE_UNKNOWN_PREFIX) := Error_Record(CODE_UNKNOWN_PREFIX, MSG_UNKNOWN_PREFIX); -- -20013 + Errors(CODE_TABLE_NOT_EXISTS) := Error_Record(CODE_TABLE_NOT_EXISTS, MSG_TABLE_NOT_EXISTS); -- -20014 + Errors(CODE_COLUMN_NOT_EXISTS) := Error_Record(CODE_COLUMN_NOT_EXISTS, MSG_COLUMN_NOT_EXISTS); -- -20015 + Errors(CODE_UNSUPPORTED_DATA_TYPE) := Error_Record(CODE_UNSUPPORTED_DATA_TYPE, MSG_UNSUPPORTED_DATA_TYPE); -- -20016 + Errors(CODE_MISSING_SOURCE_KEY) := Error_Record(CODE_MISSING_SOURCE_KEY, MSG_MISSING_SOURCE_KEY); -- -20017 + Errors(CODE_NULL_SOURCE_FILE_CONFIG_KEY) := Error_Record(CODE_NULL_SOURCE_FILE_CONFIG_KEY, MSG_NULL_SOURCE_FILE_CONFIG_KEY); -- -20018 + Errors(CODE_DUPLICATED_SOURCE_KEY) := Error_Record(CODE_DUPLICATED_SOURCE_KEY, MSG_DUPLICATED_SOURCE_KEY); -- -20019 + Errors(CODE_MISSING_CONTAINER_CONFIG) := Error_Record(CODE_MISSING_CONTAINER_CONFIG, MSG_MISSING_CONTAINER_CONFIG); -- -20020 + Errors(CODE_MULTIPLE_CONTAINER_ENTRIES) := Error_Record(CODE_MULTIPLE_CONTAINER_ENTRIES, MSG_MULTIPLE_CONTAINER_ENTRIES); -- -20021 + Errors(CODE_WRONG_DESTINATION_PARAM) := Error_Record(CODE_WRONG_DESTINATION_PARAM, MSG_WRONG_DESTINATION_PARAM); -- -20022 + Errors(CODE_FILE_NOT_EXISTS_ON_CLOUD) := Error_Record(CODE_FILE_NOT_EXISTS_ON_CLOUD, MSG_FILE_NOT_EXISTS_ON_CLOUD); -- -20023 + Errors(CODE_FILE_ALREADY_REGISTERED) := Error_Record(CODE_FILE_ALREADY_REGISTERED, MSG_FILE_ALREADY_REGISTERED); -- -20024 + Errors(CODE_WRONG_DATE_TIMESTAMP_FORMAT) := Error_Record(CODE_WRONG_DATE_TIMESTAMP_FORMAT, MSG_WRONG_DATE_TIMESTAMP_FORMAT); -- -20025 + Errors(CODE_ENVIRONMENT_NOT_SET) := Error_Record(CODE_ENVIRONMENT_NOT_SET, MSG_ENVIRONMENT_NOT_SET); -- -20026 + Errors(CODE_CONFIG_VARIABLE_NOT_SET) := Error_Record(CODE_CONFIG_VARIABLE_NOT_SET, MSG_CONFIG_VARIABLE_NOT_SET); -- -20027 + Errors(CODE_NOT_INPUT_SOURCE_FILE_TYPE) := Error_Record(CODE_NOT_INPUT_SOURCE_FILE_TYPE, MSG_NOT_INPUT_SOURCE_FILE_TYPE); -- -20028 + Errors(CODE_EXP_DATA_FOR_ARCH_FAILED) := Error_Record(CODE_EXP_DATA_FOR_ARCH_FAILED, MSG_EXP_DATA_FOR_ARCH_FAILED); -- -20029 + Errors(CODE_RESTORE_FILE_FROM_TRASH) := Error_Record(CODE_RESTORE_FILE_FROM_TRASH, MSG_RESTORE_FILE_FROM_TRASH); -- -20030 + Errors(CODE_CHANGE_STAT_TO_ARCHIVED_FAILED):= Error_Record(CODE_CHANGE_STAT_TO_ARCHIVED_FAILED, MSG_CHANGE_STAT_TO_ARCHIVED_FAILED); -- -20031 + 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_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 + + END INIT_ERRORS; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_DEFAULT_ENV + RETURN VARCHAR2 + IS + vDefaultEnv CT_MRDS.a_file_manager_config.config_variable_value%TYPE; + BEGIN + select config_variable_value + into vDefaultEnv + from CT_MRDS.a_file_manager_config + where lower(environment_id)='default' + and lower(config_variable)='environmentid'; + RETURN vDefaultEnv; + EXCEPTION + WHEN NO_DATA_FOUND THEN + RETURN NULL; + END; + + ---------------------------------------------------------------------------------------------------- + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE INIT_VARIABLES( + pEnv VARCHAR2 + ) IS + BEGIN + for rec in ( + select + ENVIRONMENT_ID + ,REGION + ,NAMESPACE + ,INBOXBUCKETNAME + ,DATABUCKETNAME + ,ARCHIVEBUCKETNAME + ,CREDENTIALNAME + ,LOGGINGENABLED + ,MINLOGLEVEL + ,DEFAULTDATEFORMAT + ,CONSOLELOGGINGENABLED + from ( + select environment_id, config_variable, config_variable_value from CT_MRDS.A_FILE_MANAGER_CONFIG + where environment_id=pEnv + ) + pivot ( + min(config_variable_value) + for config_variable in ( + 'Region' as Region + ,'NameSpace' as NameSpace + ,'InboxBucketName' as InboxBucketName + ,'DataBucketName' as DataBucketName + ,'ArchiveBucketName' as ArchiveBucketName + ,'CredentialName' as CredentialName + ,'LoggingEnabled' as LoggingEnabled + ,'MinLogLevel' as MinLogLevel + ,'DefaultDateFormat' as DefaultDateFormat + ,'ConsoleLoggingEnabled' as ConsoleLoggingEnabled) + ) + ) loop + if (rec.NAMESPACE is NULL + or rec.REGION is NULL + or rec.NAMESPACE is NULL + or rec.INBOXBUCKETNAME is NULL + or rec.DATABUCKETNAME is NULL + or rec.ARCHIVEBUCKETNAME is NULL + or rec.CREDENTIALNAME is NULL + ) THEN + vgMsgTmp := MSG_CONFIG_VARIABLE_NOT_SET + ||cgBL||' '||'Details about existing Configuration Variables where environment_id='||pEnv||': ' + ||cgBL||' '||'-------------------------' + ||cgBL||' '||'Region = '||rec.Region + ||cgBL||' '||'NameSpace = '||rec.NameSpace + ||cgBL||' '||'InboxBucketName = '||rec.InboxBucketName + ||cgBL||' '||'DataBucketName = '||rec.DataBucketName + ||cgBL||' '||'ArchiveBucketName = '||rec.ArchiveBucketName + ||cgBL||' '||'CredentialName = '||rec.CredentialName + ; + LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR'); + RAISE_APPLICATION_ERROR(CODE_CONFIG_VARIABLE_NOT_SET, vgMsgTmp); + + elsif (rec.LOGGINGENABLED is NULL + or rec.MINLOGLEVEL is NULL + or rec.DEFAULTDATEFORMAT is NULL + ) THEN + vgMsgTmp := 'Missing configuration variables' + ||cgBL||' '||'Details about existing Configuration Variables where environment_id='||pEnv||': ' + ||cgBL||' '||'-------------------------' + ||cgBL||' '||'LoggingEnabled = '||rec.LoggingEnabled + ||cgBL||' '||'MinLogLevel = '||rec.MinLogLevel + ||cgBL||' '||'DefaultDateFormat = '||rec.DefaultDateFormat + ; + LOG_PROCESS_EVENT(vgMsgTmp, 'WARNING'); + + else + gvNameSpace := rec.NAMESPACE; + gvRegion := rec.REGION; + gvInboxBucketName := rec.INBOXBUCKETNAME; + gvDataBucketName := rec.DATABUCKETNAME; + gvArchiveBucketName := rec.ARCHIVEBUCKETNAME; + gvCredentialName := rec.CREDENTIALNAME; + gvInboxBucketUri := 'https://objectstorage.'||rec.REGION||'.oraclecloud.com/n/'||rec.NAMESPACE||'/b/'||rec.INBOXBUCKETNAME||'/o/'; + gvDataBucketUri := 'https://objectstorage.'||rec.REGION||'.oraclecloud.com/n/'||rec.NAMESPACE||'/b/'||rec.DATABUCKETNAME||'/o/'; + gvArchiveBucketUri := 'https://objectstorage.'||rec.REGION||'.oraclecloud.com/n/'||rec.NAMESPACE||'/b/'||rec.ARCHIVEBUCKETNAME||'/o/'; + gvLoggingEnabled := rec.LOGGINGENABLED; + gvMinLogLevel := rec.MINLOGLEVEL; + gvDefaultDateFormat := rec.DEFAULTDATEFORMAT; + gvConsoleLoggingEnabled := NVL(rec.CONSOLELOGGINGENABLED, 'ON'); + end if; + end loop; + EXCEPTION + WHEN NO_DATA_FOUND THEN + vgMsgTmp := MSG_CONFIG_VARIABLE_NOT_SET + ||cgBL||' '||'No configuration found for environment_id='||pEnv||' in A_FILE_MANAGER_CONFIG table'; + LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', 'pEnv='||pEnv); + RAISE_APPLICATION_ERROR(CODE_CONFIG_VARIABLE_NOT_SET, vgMsgTmp); + WHEN OTHERS THEN + vgMsgTmp := 'Unexpected error while initializing variables for environment: '||pEnv + ||cgBL||' '||'SQLERRM: '||SQLERRM; + LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', 'pEnv='||pEnv); + RAISE; + END INIT_VARIABLES; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_ERROR_MESSAGE( + pCode PLS_INTEGER + ) RETURN VARCHAR2 + IS + BEGIN + RETURN Errors(pCode).message; + EXCEPTION + WHEN NO_DATA_FOUND THEN + LOG_PROCESS_EVENT('No error message found for pCode='||pCode , 'WARNING', 'pCode='||pCode); + LOG_PROCESS_EVENT('Update ENV_MANAGER package header with new code.' , 'WARNING', 'pCode='||pCode); + RETURN NULL; + WHEN OTHERS THEN + LOG_PROCESS_EVENT(MSG_UNKNOWN , 'ERROR', 'pCode='||pCode); + RAISE_APPLICATION_ERROR(CODE_UNKNOWN, MSG_UNKNOWN); + END GET_ERROR_MESSAGE; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_ERROR_STACK( + pFormat VARCHAR2 + ,pCode PLS_INTEGER + ,pSourceFileReceivedKey CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL + ) RETURN VARCHAR2 + IS + vFullErrorCore VARCHAR2(32000); + vFullErrorMsg VARCHAR2(32000); + BEGIN +-- vgErrorMessage := SQLERRM|| cgBL; +-- vgErrorStack := DBMS_UTILITY.FORMAT_ERROR_STACK; +-- vgErrorBacktrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE; + vFullErrorCore :='Error Message:' + ||cgBL|| SQLERRM|| cgBL + ||'-------------------------------------------------------' + ||cgBL||'Error Stack:' + ||cgBL|| DBMS_UTILITY.FORMAT_ERROR_STACK + ||'-------------------------------------------------------' + ||cgBL||'Error Backtrace:' + ||cgBL|| DBMS_UTILITY.FORMAT_ERROR_BACKTRACE; +-- vFullErrorCore := REGEXP_REPLACE (vFullErrorCore, pCode||': ', pCode||': '||GET_ERROR_MESSAGE(pCode) , 1, 1); + IF (pFormat = 'TABLE') THEN + vFullErrorMsg := vFullErrorCore; + ELSE + vFullErrorMsg := cgBL||'------------------------------------------------------+' + ||cgBL||vFullErrorCore + ||'------------------------------------------------------+'; + END IF; +-- IF pSourceFileReceivedKey is not null THEN +-- vFullErrorMsg := vFullErrorMsg ||cgBL||GET_DET_SOURCE_FILE_RECEIVED_INFO(pSourceFileReceivedKey,1,1,1); +-- END IF; + + RETURN vFullErrorMsg; + EXCEPTION + WHEN OTHERS THEN + LOG_PROCESS_EVENT(MSG_UNKNOWN , 'ERROR', 'pFormat='||pFormat); + RETURN NULL; + END GET_ERROR_STACK; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION FORMAT_PARAMETERS( + pParameterList SYS.ODCIVARCHAR2LIST + ) RETURN VARCHAR2 IS + vResult VARCHAR2(10000); + BEGIN + FOR i IN 1 .. pParameterList.COUNT LOOP +-- dbms_output.put_line('pParameterList(i): '||pParameterList(i)); + if i < pParameterList.COUNT then vResult := vResult || replace(pParameterList(i), '''NULL''', 'NULL') ||' ,'|| cgBL; + else vResult := vResult || replace(pParameterList(i), '''NULL''', 'NULL'); + end if; + END LOOP; + RETURN vResult; + EXCEPTION + WHEN OTHERS THEN + LOG_PROCESS_EVENT('Error while formating parameters.' , 'WARNING'); + RETURN NULL; + END FORMAT_PARAMETERS; + + ---------------------------------------------------------------------------------------------------- + + + + PROCEDURE LOG_PROCESS_EVENT ( + pLogMessage VARCHAR2 + ,pLogLevel VARCHAR2 DEFAULT 'ERROR' + ,pParameters VARCHAR2 DEFAULT NULL + ,pProcessName VARCHAR2 DEFAULT 'FILE_MANAGER' + ) IS + PRAGMA AUTONOMOUS_TRANSACTION; + + vLoggingEnabled VARCHAR2(10); + vMinLogLevel VARCHAR2(10); + vCallStack VARCHAR2(10000); + vProcedureName VARCHAR2(100); + vProcedureLevel PLS_INTEGER; + vTotalLines PLS_INTEGER; + vCurrentLine PLS_INTEGER; + + -- Map of priority level + TYPE logLevelMap IS TABLE OF NUMBER INDEX BY VARCHAR2(10); + vLogLevels logLevelMap; + + BEGIN + -- Prority logging level (higher -> more important) + vLogLevels('DEBUG') := 1; + vLogLevels('INFO') := 2; + vLogLevels('WARNING') := 3; + vLogLevels('ERROR') := 4; + + -- Check id logging is TURN-OFF + IF gvLoggingEnabled = 'OFF' THEN + RETURN; + END IF; + -- Check logging level + IF vLogLevels(pLogLevel) < vLogLevels(gvMinLogLevel) THEN + RETURN; + END IF; + + vCallStack := DBMS_UTILITY.FORMAT_CALL_STACK; + vProcedureName := REGEXP_SUBSTR(vCallStack, 'package body\s+\w+\.(\w+\.\w+)', 1, 2, NULL, 1); + vTotalLines := REGEXP_COUNT(vCallStack, CHR(10)) + 1; + vCurrentLine := REGEXP_COUNT(SUBSTR(vCallStack, 1, INSTR(vCallStack, vProcedureName) - 1), CHR(10)) + 1; + vProcedureLevel := (vTotalLines - vCurrentLine + 1) - 3; + vProcedureName := LPAD(vProcedureName, LENGTH(vProcedureName) + 2*vProcedureLevel, ' '); + + INSERT INTO CT_MRDS.A_PROCESS_LOG (guid, username, osuser, machine, module, process_name, procedure_name, procedure_parameters, log_level, log_message) + VALUES (guid, gvUsername, gvOsuser, gvMachine, gvModule, pProcessName, vProcedureName, pParameters, pLogLevel, pLogMessage); + + COMMIT; + + -- Also output to console for immediate visibility (if enabled) + IF gvConsoleLoggingEnabled = 'ON' THEN + DBMS_OUTPUT.PUT_LINE('[' || TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') || '] [' || pLogLevel || '] ' || vProcedureName || ': ' || pLogMessage); + END IF; + + END LOG_PROCESS_EVENT; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE LOG_PROCESS_ERROR( + pLogMessage IN VARCHAR2, + pParameters IN VARCHAR2 DEFAULT NULL, + pProcessName IN VARCHAR2 DEFAULT 'FILE_MANAGER' + ) IS + PRAGMA AUTONOMOUS_TRANSACTION; + + vCallStack VARCHAR2(32767); + vErrorStack VARCHAR2(32767); + vErrorBacktrace VARCHAR2(32767); + vAdjustedBacktrace VARCHAR2(32767); + vErrorContext VARCHAR2(4000); + vProcName VARCHAR2(100); + vProcedureLevel PLS_INTEGER; + vTotalLines PLS_INTEGER; + vCurrentLine PLS_INTEGER; + vFullErrorMessage CLOB; + vTimestamp VARCHAR2(30); + vSessionInfo VARCHAR2(1000); + + BEGIN + -- Check if logging is disabled + IF gvLoggingEnabled = 'OFF' THEN + RETURN; + END IF; + + -- Capture all available error information + vErrorStack := DBMS_UTILITY.FORMAT_ERROR_STACK; + vErrorBacktrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE; + vCallStack := DBMS_UTILITY.FORMAT_CALL_STACK; + vTimestamp := TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'); + + -- Capture session information for better context + vSessionInfo := 'Session ID: ' || SYS_CONTEXT('USERENV', 'SID') || + ', User: ' || SYS_CONTEXT('USERENV', 'SESSION_USER') || + ', Module: ' || SYS_CONTEXT('USERENV', 'MODULE') || + ', Client Info: ' || NVL(SYS_CONTEXT('USERENV', 'CLIENT_INFO'), 'N/A') || + ', Action: ' || NVL(SYS_CONTEXT('USERENV', 'ACTION'), 'N/A'); + + -- Build error context information + vErrorContext := 'Environment: ' || gvEnv || + ', Process: ' || NVL(pProcessName, 'UNKNOWN') || + ', Timestamp: ' || vTimestamp || + ', SQLCODE: ' || SQLCODE || + ', Transaction Active: ' || CASE WHEN DBMS_TRANSACTION.STEP_ID IS NOT NULL THEN 'YES' ELSE 'NO' END; + + -- Extract procedure name and nesting level from call stack + -- Always extract actual procedure name from call stack for precise error location + vProcName := REGEXP_SUBSTR(vCallStack, 'package body\s+\w+\.(\w+\.\w+)', 1, 2, NULL, 1); + + -- If we couldn't extract procedure name from call stack, use provided process name + IF vProcName IS NULL THEN + vProcName := NVL(pProcessName, 'UNKNOWN'); + END IF; + + vTotalLines := REGEXP_COUNT(vCallStack, CHR(10)) + 1; + vCurrentLine := REGEXP_COUNT(SUBSTR(vCallStack, 1, INSTR(vCallStack, vProcName) - 1), CHR(10)) + 1; + vProcedureLevel := (vTotalLines - vCurrentLine + 1) - 3; + vProcName := LPAD(vProcName, LENGTH(vProcName) + 2*vProcedureLevel, ' '); + + -- Enhance line number display to show direct _BODY.sql file line numbers + -- Since packages are now split into separate _SPEC and _BODY files, line numbers map directly + vAdjustedBacktrace := REGEXP_REPLACE(vErrorBacktrace, + 'at "CT_MRDS\.FILE_MANAGER", line ([0-9]+)', + 'at "CT_MRDS.FILE_MANAGER", line \1 (-> FILE_MANAGER_BODY.sql:line \1)', 1, 0, 'i'); + + vAdjustedBacktrace := REGEXP_REPLACE(vAdjustedBacktrace, + 'at "CT_MRDS\.ENV_MANAGER", line ([0-9]+)', + 'at "CT_MRDS.ENV_MANAGER", line \1 (-> ENV_MANAGER_BODY.sql:line \1)', 1, 0, 'i'); + + -- Build comprehensive error message with professional formatting + vFullErrorMessage := 'ERROR REPORT' || cgBL || + '-------------------------------------------------------' || cgBL || + 'ERROR SUMMARY' || cgBL || + ' Message: ' || pLogMessage || cgBL || + ' Context: ' || vErrorContext || cgBL || + '-------------------------------------------------------' || cgBL || + 'SESSION INFORMATION' || cgBL || + ' ' || vSessionInfo || cgBL || + '-------------------------------------------------------' || cgBL || + 'ERROR STACK (Oracle Internal)' || cgBL || + vErrorStack || + '-------------------------------------------------------' || cgBL || + 'BACKTRACE INFORMATION (Oracle Internal)' || cgBL || + vErrorBacktrace || + '-------------------------------------------------------' || cgBL || + 'CALL STACK (Execution Path)' || cgBL || + vCallStack || + '-------------------------------------------------------' || cgBL || + 'QUICK REFERENCE' || cgBL || + ' SQLCODE: ' || SQLCODE || cgBL || + ' SQLERRM: ' || SQLERRM || cgBL || + ' Timestamp: ' || vTimestamp || cgBL || + ' Parameters: ' || NVL(pParameters, 'None provided') || cgBL || + '-------------------------------------------------------'; + + -- Insert comprehensive error record into log table + -- Note: LOG_MESSAGE is VARCHAR2(4000), so we'll truncate if needed but include key info + INSERT INTO CT_MRDS.A_PROCESS_LOG (guid, username, osuser, machine, module, process_name, procedure_name, procedure_parameters, log_level, log_message) + VALUES (guid, gvUsername, gvOsuser, gvMachine, gvModule, NVL(pProcessName, 'FILE_MANAGER'), vProcName, pParameters, 'ERROR', + CASE + WHEN LENGTH(vFullErrorMessage) <= 4000 THEN vFullErrorMessage + ELSE SUBSTR(vFullErrorMessage, 1, 3950) || '... [TRUNCATED]' + END); + + COMMIT; + + -- Enhanced console output for immediate visibility (if enabled) + IF gvConsoleLoggingEnabled = 'ON' THEN + DBMS_OUTPUT.PUT_LINE('======================================================='); + DBMS_OUTPUT.PUT_LINE('ERROR DETECTED AT: ' || vTimestamp); + DBMS_OUTPUT.PUT_LINE('PROCEDURE: ' || NVL(vProcName, 'UNKNOWN')); + DBMS_OUTPUT.PUT_LINE('MESSAGE: ' || pLogMessage); + DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE || ' | ENVIRONMENT: ' || gvEnv); + -- Extract and show the most relevant file and line number + IF INSTR(vAdjustedBacktrace, '-> ') > 0 THEN + DBMS_OUTPUT.PUT_LINE('SOURCE FILE LOCATION: ' || REGEXP_SUBSTR(vAdjustedBacktrace, '-> [^)]+')); + END IF; + DBMS_OUTPUT.PUT_LINE('FULL DETAILS: Query A_PROCESS_LOG table for complete diagnostic info'); + DBMS_OUTPUT.PUT_LINE('QUERY (This Error): SELECT * FROM CT_MRDS.A_PROCESS_LOG WHERE GUID = ''' || guid || ''' ORDER BY LOG_TIMESTAMP DESC;'); + DBMS_OUTPUT.PUT_LINE('QUERY (Recent All): SELECT * FROM CT_MRDS.A_PROCESS_LOG WHERE LOG_TIMESTAMP >= SYSDATE - 1/1440 ORDER BY LOG_TIMESTAMP DESC;'); + DBMS_OUTPUT.PUT_LINE('======================================================='); + END IF; + + END LOG_PROCESS_ERROR; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION ANALYZE_VALIDATION_ERRORS( + pValidationLogTable VARCHAR2, + pTemplateSchema VARCHAR2, + pTemplateTable VARCHAR2, + pCsvFileUri VARCHAR2 + ) RETURN VARCHAR2 + IS + vAnalysisReport CLOB := ''; + vCsvHeader VARCHAR2(4000); + vExpectedOrder VARCHAR2(4000); + vCsvOrder VARCHAR2(4000); + vErrorDetails VARCHAR2(32000) := ''; + vSolutions VARCHAR2(4000); + vColumnMismatch VARCHAR2(1000); + vErrorCount NUMBER := 0; + vFirstDataError VARCHAR2(1000); + vErrorColumn VARCHAR2(100); + vErrorValue VARCHAR2(500); + vExpectedType VARCHAR2(100); + vTemplateColCount NUMBER := 0; + vCsvColCount NUMBER := 0; + vExcessColumns VARCHAR2(2000); + vCsvFirstLine VARCHAR2(4000); + + -- Cursor for template table columns + CURSOR c_template_columns IS + SELECT COLUMN_NAME, DATA_TYPE, COLUMN_ID + FROM ALL_TAB_COLUMNS + WHERE OWNER = UPPER(REGEXP_SUBSTR(pTemplateSchema || '.' || pTemplateTable, '^([^.]+)')) + AND TABLE_NAME = UPPER(REGEXP_SUBSTR(pTemplateSchema || '.' || pTemplateTable, '\.(.+)$', 1, 1, NULL, 1)) + ORDER BY COLUMN_ID; + + BEGIN + -- Build expected column order from template table and count columns + FOR rec IN c_template_columns LOOP + IF vExpectedOrder IS NOT NULL THEN + vExpectedOrder := vExpectedOrder || ', '; + END IF; + vExpectedOrder := vExpectedOrder || rec.COLUMN_NAME; + vTemplateColCount := vTemplateColCount + 1; + END LOOP; + + -- Parse validation log table for errors and CSV structure + BEGIN + -- Try to extract error information from the validation log table + EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || pValidationLogTable || + ' WHERE record LIKE ''error processing column%''' + INTO vErrorCount; + + -- Get first error details + IF vErrorCount > 0 THEN + EXECUTE IMMEDIATE 'SELECT record FROM ' || pValidationLogTable || + ' WHERE record LIKE ''error processing column%'' AND ROWNUM = 1' + INTO vFirstDataError; + + -- Parse error to extract column name and error type + vErrorColumn := REGEXP_SUBSTR(vFirstDataError, 'error processing column ([A-Z_]+)', 1, 1, NULL, 1); + + -- Try to get the actual error value from ORA-01722 message + BEGIN + EXECUTE IMMEDIATE 'SELECT record FROM ' || pValidationLogTable || + ' WHERE record LIKE ''ORA-01722%'' AND ROWNUM = 1' + INTO vFirstDataError; + vErrorValue := REGEXP_SUBSTR(vFirstDataError, 'string value containing ''([^'']+)''', 1, 1, NULL, 1); + EXCEPTION + WHEN NO_DATA_FOUND THEN + vErrorValue := 'unknown value'; + WHEN OTHERS THEN + vErrorValue := 'parsing error'; + END; + END IF; + + -- Try to extract CSV structure from validation log field definitions + BEGIN + EXECUTE IMMEDIATE ' + SELECT LISTAGG( + REGEXP_SUBSTR(record, ''^\s+([A-Z_]+)\s+'', 1, 1, NULL, 1), + '', '' + ) WITHIN GROUP (ORDER BY ROWNUM) + FROM ' || pValidationLogTable || ' + WHERE record LIKE '' %CHAR%'' + AND record NOT LIKE ''%Fields in Data Source%'' + AND REGEXP_SUBSTR(record, ''^\s+([A-Z_]+)\s+'') IS NOT NULL' + INTO vCsvOrder; + + -- Count CSV columns from parsed structure + IF vCsvOrder IS NOT NULL THEN + vCsvColCount := REGEXP_COUNT(vCsvOrder, ',') + 1; + END IF; + + EXCEPTION + WHEN OTHERS THEN + vCsvOrder := 'Unable to determine CSV column order from validation log'; + END; + + -- Alternative method: Try to read first line of CSV directly for column count + IF vCsvColCount = 0 THEN + BEGIN + -- This is a fallback - try to get CSV header from external source if possible + -- Note: This would require DBMS_CLOUD.GET_OBJECT or similar approach + -- For now, we'll rely on the validation log parsing + NULL; + EXCEPTION + WHEN OTHERS THEN + NULL; + END; + END IF; + + EXCEPTION + WHEN OTHERS THEN + vErrorDetails := 'Error analyzing validation log: ' || SQLERRM; + END; + + -- Detect column order mismatch and excess columns + IF vCsvOrder IS NOT NULL AND vExpectedOrder IS NOT NULL THEN + IF UPPER(REPLACE(vCsvOrder, ' ', '')) != UPPER(REPLACE(vExpectedOrder, ' ', '')) THEN + vColumnMismatch := 'YES'; + ELSE + vColumnMismatch := 'NO'; + END IF; + END IF; + + -- Check for excess columns + IF vCsvColCount > vTemplateColCount THEN + -- Try to identify which columns are excess + IF vCsvOrder IS NOT NULL THEN + -- Parse CSV columns and compare with template + DECLARE + vCsvCols SYS.ODCIVARCHAR2LIST; + vTemplateCols SYS.ODCIVARCHAR2LIST; + vExcessFound VARCHAR2(1) := 'N'; + i NUMBER; + BEGIN + -- Split CSV columns + SELECT TRIM(REGEXP_SUBSTR(vCsvOrder, '[^,]+', 1, LEVEL)) + BULK COLLECT INTO vCsvCols + FROM DUAL + CONNECT BY REGEXP_SUBSTR(vCsvOrder, '[^,]+', 1, LEVEL) IS NOT NULL; + + -- Split template columns + SELECT TRIM(REGEXP_SUBSTR(vExpectedOrder, '[^,]+', 1, LEVEL)) + BULK COLLECT INTO vTemplateCols + FROM DUAL + CONNECT BY REGEXP_SUBSTR(vExpectedOrder, '[^,]+', 1, LEVEL) IS NOT NULL; + + -- Find excess columns (those in CSV but not in template) + FOR i IN 1..vCsvCols.COUNT LOOP + DECLARE + vFoundInTemplate BOOLEAN := FALSE; + j NUMBER; + BEGIN + -- Check if CSV column exists in template + FOR j IN 1..vTemplateCols.COUNT LOOP + IF UPPER(TRIM(vCsvCols(i))) = UPPER(TRIM(vTemplateCols(j))) THEN + vFoundInTemplate := TRUE; + EXIT; + END IF; + END LOOP; + + -- If not found in template, it's an excess column + IF NOT vFoundInTemplate THEN + IF vExcessFound = 'Y' THEN + vExcessColumns := vExcessColumns || ', '; + END IF; + vExcessColumns := vExcessColumns || vCsvCols(i); + vExcessFound := 'Y'; + END IF; + END; + END LOOP; + EXCEPTION + WHEN OTHERS THEN + vExcessColumns := 'Unable to determine specific excess columns'; + END; + END IF; + END IF; + + -- Build comprehensive analysis report + vAnalysisReport := 'FILE VALIDATION FAILED - DETAILED ANALYSIS' || cgBL || + '=================================================' || cgBL || cgBL; + + -- Column structure analysis + vAnalysisReport := vAnalysisReport || + 'COLUMN STRUCTURE ANALYSIS:' || cgBL || + '---------------------------------------------------' || cgBL || + 'Template Expected Order: ' || vExpectedOrder || cgBL || + 'Template Column Count: ' || vTemplateColCount || cgBL || + 'CSV Detected Order: ' || NVL(vCsvOrder, 'Unknown') || cgBL || + 'CSV Column Count: ' || vCsvColCount || cgBL || cgBL; + + -- Report column count issues + IF vCsvColCount > vTemplateColCount THEN + vAnalysisReport := vAnalysisReport || + 'EXCESS COLUMNS DETECTED!' || cgBL || + 'CSV file has ' || (vCsvColCount - vTemplateColCount) || ' more columns than template allows.' || cgBL; + IF vExcessColumns IS NOT NULL THEN + vAnalysisReport := vAnalysisReport || + 'Excess columns found: ' || vExcessColumns || cgBL; + END IF; + vAnalysisReport := vAnalysisReport || cgBL; + END IF; + + -- Report column order issues + IF vColumnMismatch = 'YES' THEN + vAnalysisReport := vAnalysisReport || + 'COLUMN ORDER MISMATCH DETECTED!' || cgBL || + 'CSV columns are in different order than template expects.' || cgBL || cgBL; + END IF; + + -- Specific error analysis + IF vErrorCount > 0 THEN + vAnalysisReport := vAnalysisReport || + 'SPECIFIC ERRORS FOUND:' || cgBL || + '---------------------------------------------------' || cgBL; + + IF vErrorColumn IS NOT NULL THEN + -- Get expected data type for error column + FOR rec IN c_template_columns LOOP + IF rec.COLUMN_NAME = vErrorColumn THEN + vExpectedType := rec.DATA_TYPE; + EXIT; + END IF; + END LOOP; + + vAnalysisReport := vAnalysisReport || + '1. Column ' || vErrorColumn || ': Expected ' || vExpectedType || + ', received "' || NVL(vErrorValue, 'unknown value') || '" (TEXT)' || cgBL || + ' ? CSV position contains different data type than expected' || cgBL; + END IF; + + vAnalysisReport := vAnalysisReport || + 'Total validation errors found: ' || vErrorCount || cgBL || cgBL; + END IF; + + -- Solutions section + vAnalysisReport := vAnalysisReport || + 'SUGGESTED SOLUTIONS:' || cgBL || + '---------------------------------------------------' || cgBL; + + -- Solutions for excess columns + IF vCsvColCount > vTemplateColCount THEN + vAnalysisReport := vAnalysisReport || + 'FOR EXCESS COLUMNS:' || cgBL || + '• Remove extra columns from CSV file' || cgBL || + '• Keep only these columns in this order: ' || vExpectedOrder || cgBL; + IF vExcessColumns IS NOT NULL THEN + vAnalysisReport := vAnalysisReport || + '• Specifically remove: ' || vExcessColumns || cgBL; + END IF; + vAnalysisReport := vAnalysisReport || cgBL; + END IF; + + -- Solutions for column order + IF vColumnMismatch = 'YES' THEN + vAnalysisReport := vAnalysisReport || + 'FOR COLUMN ORDER:' || cgBL || + '• Reorder CSV columns to match template: ' || vExpectedOrder || cgBL || + '• Or update template table column order to match CSV file' || cgBL || cgBL; + END IF; + + -- General solutions + vAnalysisReport := vAnalysisReport || + 'GENERAL RECOMMENDATIONS:' || cgBL || + '• Ensure CSV has exactly ' || vTemplateColCount || ' columns' || cgBL || + '• Verify column names match template table exactly' || cgBL || + '• Check data types in each column match expectations' || cgBL || cgBL; + + -- Validation log reference + vAnalysisReport := vAnalysisReport || + 'TECHNICAL DETAILS:' || cgBL || + '---------------------------------------------------' || cgBL || + 'Validation Log Table: ' || pValidationLogTable || cgBL || + 'Template Table: ' || pTemplateSchema || '.' || pTemplateTable || cgBL || + 'CSV File: ' || pCsvFileUri || cgBL || + 'Query validation details: SELECT * FROM ' || pValidationLogTable || ';' || cgBL; + + RETURN vAnalysisReport; + + EXCEPTION + WHEN OTHERS THEN + RETURN 'Error generating validation analysis: ' || SQLERRM || cgBL || + 'Validation Log Table: ' || pValidationLogTable || cgBL || + 'Check table manually: SELECT * FROM ' || pValidationLogTable || ';'; + END ANALYZE_VALIDATION_ERRORS; + + ---------------------------------------------------------------------------------------------------- + -- 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 GET_PACKAGE_VERSION_INFO( + pPackageName => 'ENV_MANAGER', + pVersion => PACKAGE_VERSION, + pBuildDate => PACKAGE_BUILD_DATE, + pAuthor => PACKAGE_AUTHOR + ); + END GET_BUILD_INFO; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_VERSION_HISTORY + RETURN VARCHAR2 + IS + BEGIN + RETURN FORMAT_VERSION_HISTORY( + pPackageName => 'ENV_MANAGER', + pVersionHistory => VERSION_HISTORY + ); + END GET_VERSION_HISTORY; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_PACKAGE_VERSION_INFO( + pPackageName VARCHAR2, + pVersion VARCHAR2, + pBuildDate VARCHAR2, + pAuthor VARCHAR2 + ) RETURN VARCHAR2 + IS + BEGIN + RETURN 'Package: ' || pPackageName || cgBL || + 'Version: ' || pVersion || cgBL || + 'Build Date: ' || pBuildDate || cgBL || + 'Author: ' || pAuthor; + END GET_PACKAGE_VERSION_INFO; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION FORMAT_VERSION_HISTORY( + pPackageName VARCHAR2, + pVersionHistory VARCHAR2 + ) RETURN VARCHAR2 + IS + BEGIN + RETURN pPackageName || ' Version History:' || cgBL || pVersionHistory; + END FORMAT_VERSION_HISTORY; + + ---------------------------------------------------------------------------------------------------- + -- PACKAGE HASH + CHANGE DETECTION FUNCTIONS IMPLEMENTATION + ---------------------------------------------------------------------------------------------------- + + FUNCTION CALCULATE_PACKAGE_HASH( + pPackageOwner VARCHAR2, + pPackageName VARCHAR2, + pPackageType VARCHAR2 + ) RETURN VARCHAR2 + IS + vSourceCode CLOB; + vHash VARCHAR2(64); + vRawHash RAW(32); + BEGIN + -- Build complete source code from ALL_SOURCE using XMLAGG (no 4000 char limit) + -- CRITICAL: Cannot use LISTAGG due to VARCHAR2 limit + SELECT XMLAGG(XMLELEMENT(E, TEXT) ORDER BY LINE).GETCLOBVAL() + INTO vSourceCode + FROM ALL_SOURCE + WHERE OWNER = UPPER(pPackageOwner) + AND NAME = UPPER(pPackageName) + AND TYPE = UPPER(pPackageType); + + -- If empty, return NULL + IF vSourceCode IS NULL OR DBMS_LOB.GETLENGTH(vSourceCode) = 0 THEN + RETURN NULL; + END IF; + + -- Calculate SHA256 hash directly from CLOB + -- DBMS_CRYPTO.HASH has overload for CLOB in Oracle 19c+ + vRawHash := DBMS_CRYPTO.HASH( + src => vSourceCode, + typ => DBMS_CRYPTO.HASH_SH256 + ); + + -- Convert to hex string + vHash := LOWER(RAWTOHEX(vRawHash)); + + RETURN vHash; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + RETURN NULL; + WHEN OTHERS THEN + LOG_PROCESS_ERROR('Error calculating package hash: ' || SQLERRM, + 'pPackageOwner=' || pPackageOwner || ', pPackageName=' || pPackageName); + RETURN NULL; + END CALCULATE_PACKAGE_HASH; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE TRACK_PACKAGE_VERSION( + pPackageOwner VARCHAR2, + pPackageName VARCHAR2, + pPackageVersion VARCHAR2, + pPackageBuildDate VARCHAR2, + pPackageAuthor VARCHAR2 + ) + IS + vHashSpec VARCHAR2(64); + vHashBody VARCHAR2(64); + vLastHashSpec VARCHAR2(64); + vLastHashBody VARCHAR2(64); + vLastVersion VARCHAR2(10); + vLineCountSpec NUMBER; + vLineCountBody NUMBER; + vChangeDetected CHAR(1) := 'N'; + vChangeMessage VARCHAR2(4000); + vParameters VARCHAR2(4000); + BEGIN + vParameters := FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( + 'pPackageOwner => ''' || pPackageOwner || '''', + 'pPackageName => ''' || pPackageName || '''', + 'pPackageVersion => ''' || pPackageVersion || '''' + )); + + LOG_PROCESS_EVENT('Start TRACK_PACKAGE_VERSION', 'INFO', vParameters); + + -- Calculate current hashes + vHashSpec := CALCULATE_PACKAGE_HASH(pPackageOwner, pPackageName, 'PACKAGE'); + vHashBody := CALCULATE_PACKAGE_HASH(pPackageOwner, pPackageName, 'PACKAGE BODY'); + + -- Get line counts + BEGIN + SELECT COUNT(*) + INTO vLineCountSpec + FROM ALL_SOURCE + WHERE OWNER = UPPER(pPackageOwner) + AND NAME = UPPER(pPackageName) + AND TYPE = 'PACKAGE'; + EXCEPTION + WHEN NO_DATA_FOUND THEN + vLineCountSpec := 0; + END; + + BEGIN + SELECT COUNT(*) + INTO vLineCountBody + FROM ALL_SOURCE + WHERE OWNER = UPPER(pPackageOwner) + AND NAME = UPPER(pPackageName) + AND TYPE = 'PACKAGE BODY'; + EXCEPTION + WHEN NO_DATA_FOUND THEN + vLineCountBody := 0; + END; + + -- Get last tracked version and hashes + BEGIN + SELECT PACKAGE_VERSION, SOURCE_CODE_HASH_SPEC, SOURCE_CODE_HASH_BODY + INTO vLastVersion, vLastHashSpec, vLastHashBody + FROM CT_MRDS.A_PACKAGE_VERSION_TRACKING + WHERE PACKAGE_OWNER = UPPER(pPackageOwner) + AND PACKAGE_NAME = UPPER(pPackageName) + ORDER BY TRACKING_DATE DESC + FETCH FIRST 1 ROW ONLY; + + -- Check if hash changed but version didn't + IF (vHashSpec != vLastHashSpec OR NVL(vHashBody,'X') != NVL(vLastHashBody,'X')) + AND pPackageVersion = vLastVersion THEN + + vChangeDetected := 'Y'; + vChangeMessage := 'WARNING: Source code changed without version update!' || cgBL || + 'Last Version: ' || vLastVersion || cgBL || + 'Current Version: ' || pPackageVersion || cgBL; + + IF vHashSpec != vLastHashSpec THEN + vChangeMessage := vChangeMessage || + 'SPEC Changed - Hash: ' || SUBSTR(vHashSpec, 1, 16) || '... (was: ' || + SUBSTR(vLastHashSpec, 1, 16) || '...)' || cgBL; + END IF; + + IF NVL(vHashBody,'X') != NVL(vLastHashBody,'X') THEN + vChangeMessage := vChangeMessage || + 'BODY Changed - Hash: ' || SUBSTR(vHashBody, 1, 16) || '... (was: ' || + SUBSTR(NVL(vLastHashBody,'NULL'), 1, 16) || '...)' || cgBL; + END IF; + + vChangeMessage := vChangeMessage || + 'RECOMMENDATION: Update PACKAGE_VERSION constant and PACKAGE_BUILD_DATE'; + + LOG_PROCESS_EVENT(vChangeMessage, 'WARNING', vParameters); + END IF; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + -- First time tracking this package + vChangeDetected := 'N'; + vChangeMessage := 'First tracking record for this package'; + LOG_PROCESS_EVENT(vChangeMessage, 'INFO', vParameters); + END; + + -- Insert tracking record + INSERT INTO CT_MRDS.A_PACKAGE_VERSION_TRACKING ( + PACKAGE_OWNER, + PACKAGE_NAME, + PACKAGE_TYPE, + PACKAGE_VERSION, + PACKAGE_BUILD_DATE, + PACKAGE_AUTHOR, + SOURCE_CODE_HASH_SPEC, + SOURCE_CODE_HASH_BODY, + LINE_COUNT_SPEC, + LINE_COUNT_BODY, + DETECTED_CHANGE_WITHOUT_VERSION, + CHANGE_DETECTION_MESSAGE + ) VALUES ( + UPPER(pPackageOwner), + UPPER(pPackageName), + 'BOTH', + pPackageVersion, + pPackageBuildDate, + pPackageAuthor, + vHashSpec, + vHashBody, + vLineCountSpec, + vLineCountBody, + vChangeDetected, + vChangeMessage + ); + + COMMIT; + + LOG_PROCESS_EVENT('End TRACK_PACKAGE_VERSION - Record inserted', 'INFO', vParameters); + + EXCEPTION + WHEN OTHERS THEN + LOG_PROCESS_ERROR('Error in TRACK_PACKAGE_VERSION: ' || SQLERRM, vParameters); + RAISE; + END TRACK_PACKAGE_VERSION; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION CHECK_PACKAGE_CHANGES( + pPackageOwner VARCHAR2, + pPackageName VARCHAR2 + ) RETURN VARCHAR2 + IS + vCurrentHashSpec VARCHAR2(64); + vCurrentHashBody VARCHAR2(64); + vLastHashSpec VARCHAR2(64); + vLastHashBody VARCHAR2(64); + vLastVersion VARCHAR2(10); + vLastTrackingDate TIMESTAMP; + vChangeReport VARCHAR2(4000); + vSpecChanged BOOLEAN := FALSE; + vBodyChanged BOOLEAN := FALSE; + BEGIN + -- Get current hashes + vCurrentHashSpec := CALCULATE_PACKAGE_HASH(pPackageOwner, pPackageName, 'PACKAGE'); + vCurrentHashBody := CALCULATE_PACKAGE_HASH(pPackageOwner, pPackageName, 'PACKAGE BODY'); + + -- Get last tracked hashes + BEGIN + SELECT PACKAGE_VERSION, SOURCE_CODE_HASH_SPEC, SOURCE_CODE_HASH_BODY, TRACKING_DATE + INTO vLastVersion, vLastHashSpec, vLastHashBody, vLastTrackingDate + FROM CT_MRDS.A_PACKAGE_VERSION_TRACKING + WHERE PACKAGE_OWNER = UPPER(pPackageOwner) + AND PACKAGE_NAME = UPPER(pPackageName) + ORDER BY TRACKING_DATE DESC + FETCH FIRST 1 ROW ONLY; + EXCEPTION + WHEN NO_DATA_FOUND THEN + RETURN 'Package ' || pPackageOwner || '.' || pPackageName || ' has never been tracked.' || cgBL || + 'Run TRACK_PACKAGE_VERSION to establish baseline.'; + END; + + -- Check for changes + IF vCurrentHashSpec != vLastHashSpec THEN + vSpecChanged := TRUE; + END IF; + + IF NVL(vCurrentHashBody, 'X') != NVL(vLastHashBody, 'X') THEN + vBodyChanged := TRUE; + END IF; + + -- Build report + IF vSpecChanged OR vBodyChanged THEN + vChangeReport := 'WARNING: Package ' || pPackageOwner || '.' || pPackageName || ' has changed!' || cgBL || + '========================================' || cgBL || + 'Last Tracked Version: ' || vLastVersion || cgBL || + 'Last Tracked Date: ' || TO_CHAR(vLastTrackingDate, 'YYYY-MM-DD HH24:MI:SS') || cgBL || + cgBL; + + IF vSpecChanged THEN + vChangeReport := vChangeReport || + 'SPECIFICATION Changed:' || cgBL || + ' Current Hash: ' || SUBSTR(vCurrentHashSpec, 1, 16) || '...' || cgBL || + ' Last Hash: ' || SUBSTR(vLastHashSpec, 1, 16) || '...' || cgBL || + cgBL; + END IF; + + IF vBodyChanged THEN + vChangeReport := vChangeReport || + 'BODY Changed:' || cgBL || + ' Current Hash: ' || SUBSTR(NVL(vCurrentHashBody, 'NULL'), 1, 16) || '...' || cgBL || + ' Last Hash: ' || SUBSTR(NVL(vLastHashBody, 'NULL'), 1, 16) || '...' || cgBL || + cgBL; + END IF; + + vChangeReport := vChangeReport || + 'RECOMMENDATION:' || cgBL || + '1. Update PACKAGE_VERSION constant' || cgBL || + '2. Update PACKAGE_BUILD_DATE constant' || cgBL || + '3. Add entry to VERSION_HISTORY' || cgBL || + '4. Call TRACK_PACKAGE_VERSION to update tracking'; + ELSE + vChangeReport := 'OK: Package ' || pPackageOwner || '.' || pPackageName || ' has not changed.' || cgBL || + 'Last Tracked: ' || TO_CHAR(vLastTrackingDate, 'YYYY-MM-DD HH24:MI:SS') || cgBL || + 'Version: ' || vLastVersion; + END IF; + + RETURN vChangeReport; + + EXCEPTION + WHEN OTHERS THEN + RETURN 'Error checking package changes: ' || SQLERRM; + END CHECK_PACKAGE_CHANGES; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_PACKAGE_HASH_INFO( + pPackageOwner VARCHAR2, + pPackageName VARCHAR2 + ) RETURN VARCHAR2 + IS + vCurrentHashSpec VARCHAR2(64); + vCurrentHashBody VARCHAR2(64); + vLastHashSpec VARCHAR2(64); + vLastHashBody VARCHAR2(64); + vLastVersion VARCHAR2(10); + vLastTrackingDate TIMESTAMP; + vLastChangeDetected CHAR(1); + vInfo VARCHAR2(4000); + BEGIN + -- Get current hashes + vCurrentHashSpec := CALCULATE_PACKAGE_HASH(pPackageOwner, pPackageName, 'PACKAGE'); + vCurrentHashBody := CALCULATE_PACKAGE_HASH(pPackageOwner, pPackageName, 'PACKAGE BODY'); + + -- Get last tracking info + BEGIN + SELECT PACKAGE_VERSION, + SOURCE_CODE_HASH_SPEC, + SOURCE_CODE_HASH_BODY, + TRACKING_DATE, + DETECTED_CHANGE_WITHOUT_VERSION + INTO vLastVersion, vLastHashSpec, vLastHashBody, vLastTrackingDate, vLastChangeDetected + FROM CT_MRDS.A_PACKAGE_VERSION_TRACKING + WHERE PACKAGE_OWNER = UPPER(pPackageOwner) + AND PACKAGE_NAME = UPPER(pPackageName) + ORDER BY TRACKING_DATE DESC + FETCH FIRST 1 ROW ONLY; + EXCEPTION + WHEN NO_DATA_FOUND THEN + RETURN 'Package: ' || pPackageOwner || '.' || pPackageName || cgBL || + 'Status: Never tracked' || cgBL || + 'Current Hash (SPEC): ' || SUBSTR(vCurrentHashSpec, 1, 16) || '...' || cgBL || + 'Current Hash (BODY): ' || SUBSTR(NVL(vCurrentHashBody, 'NULL'), 1, 16) || '...'; + END; + + -- Build info report + vInfo := 'Package: ' || pPackageOwner || '.' || pPackageName || cgBL || + 'Current Version: ' || vLastVersion || cgBL || + 'Last Tracked: ' || TO_CHAR(vLastTrackingDate, 'YYYY-MM-DD HH24:MI:SS') || cgBL || + cgBL || + 'Current Hash (SPEC): ' || SUBSTR(vCurrentHashSpec, 1, 32) || '...' || cgBL || + 'Last Hash (SPEC): ' || SUBSTR(vLastHashSpec, 1, 32) || '...' || cgBL; + + IF vCurrentHashBody IS NOT NULL OR vLastHashBody IS NOT NULL THEN + vInfo := vInfo || + 'Current Hash (BODY): ' || SUBSTR(NVL(vCurrentHashBody, 'NULL'), 1, 32) || '...' || cgBL || + 'Last Hash (BODY): ' || SUBSTR(NVL(vLastHashBody, 'NULL'), 1, 32) || '...' || cgBL; + END IF; + + vInfo := vInfo || cgBL; + + -- Status + IF vCurrentHashSpec = vLastHashSpec AND NVL(vCurrentHashBody, 'X') = NVL(vLastHashBody, 'X') THEN + vInfo := vInfo || 'Status: OK - No changes detected'; + ELSE + vInfo := vInfo || 'Status: CHANGED - Source code modified since last tracking'; + END IF; + + IF vLastChangeDetected = 'Y' THEN + vInfo := vInfo || cgBL || 'Last Tracking Warning: Change detected without version update'; + END IF; + + RETURN vInfo; + + EXCEPTION + WHEN OTHERS THEN + RETURN 'Error getting package hash info: ' || SQLERRM; + END GET_PACKAGE_HASH_INFO; + + ---------------------------------------------------------------------------------------------------- + +BEGIN + INIT_ERRORS; + guid := sys_guid(); + gvUsername := SYS_CONTEXT('USERENV', 'SESSION_USER'); + gvOsuser := SYS_CONTEXT('USERENV', 'OS_USER'); + gvMachine := SYS_CONTEXT('USERENV', 'HOST'); + gvModule := SYS_CONTEXT('USERENV', 'MODULE'); + + -- Get info about EnvironmentID. Without it package cannot proceed further. + -- Information about environment is needed to get proper configuration values + -- It can be set up in two different ways : + -- 1. Set it on session level: execute DBMS_SESSION.SET_IDENTIFIER (client_id => 'dev'); + -- 2. Set it on configuration level: Insert into CT_MRDS.A_FILE_MANAGER_CONFIG (ENVIRONMENT_ID,CONFIG_VARIABLE,CONFIG_VARIABLE_VALUE) values ('default','environment_id','dev'); + -- Session level setup (1.) takes precedence over configuration level one (2.) + + gvEnv := nvl(SYS_CONTEXT ('USERENV', 'CLIENT_IDENTIFIER'), GET_DEFAULT_ENV()); + if gvEnv is null then + dbms_output.put_line(MSG_ENVIRONMENT_NOT_SET); + LOG_PROCESS_EVENT(MSG_ENVIRONMENT_NOT_SET, 'ERROR'); + RAISE_APPLICATION_ERROR(CODE_ENVIRONMENT_NOT_SET, MSG_ENVIRONMENT_NOT_SET); + else + dbms_output.put_line('EnvironmentID set to: '||gvEnv); + end if; + + INIT_VARIABLES(pEnv => gvEnv); +END ENV_MANAGER; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ERR_LOG.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ERR_LOG.sql new file mode 100644 index 0000000..f9728b1 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/ERR_LOG.sql @@ -0,0 +1,25 @@ +-------------------------------------------------------- +-- DDL for Table ERR_LOG +-------------------------------------------------------- + + CREATE TABLE "CT_MRDS"."ERR_LOG" + ( "ERR_LOG_KEY" NUMBER(*,0), + "A_WORKFLOW_HISTORY_KEY" NUMBER(38,0), + "ERR_MESSAGE_FK" NUMBER, + "ERR_SEVERITY_FK" NUMBER, + "ERR_WORKFLOW_RUN_ID" CHAR(17 BYTE) COLLATE "USING_NLS_COMP", + "ERR_WORKFLOW_NAME" CHAR(18 BYTE) COLLATE "USING_NLS_COMP", + "ERR_MAPPING_NAME" CHAR(74 BYTE) COLLATE "USING_NLS_COMP", + "ERR_LOCATION" CHAR(74 BYTE) COLLATE "USING_NLS_COMP", + "ERR_SOURCE" CHAR(22 BYTE) COLLATE "USING_NLS_COMP", + "ERR_KEY_BUSINESS" CHAR(6 BYTE) COLLATE "USING_NLS_COMP", + "ERR_KEY_BUSINESS_VALUE" CHAR(14 BYTE) COLLATE "USING_NLS_COMP", + "ERR_KEY_TECHNICAL" CHAR(22 BYTE) COLLATE "USING_NLS_COMP", + "ERR_KEY_TECHNICAL_VALUE" VARCHAR2(40 BYTE) COLLATE "USING_NLS_COMP", + "ERR_DESCRIPTION" CHAR(94 BYTE) COLLATE "USING_NLS_COMP", + "ERR_MESSAGE" VARCHAR2(255 BYTE) COLLATE "USING_NLS_COMP", + "INDEP_SUBPROCESS_FK" NUMBER(38,0) + ) DEFAULT COLLATION "USING_NLS_COMP" SEGMENT CREATION DEFERRED + PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 + COLUMN STORE COMPRESS FOR QUERY HIGH ROW LEVEL LOCKING LOGGING + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_ARCHIVER.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_ARCHIVER.sql new file mode 100644 index 0000000..7671341 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_ARCHIVER.sql @@ -0,0 +1,283 @@ +-------------------------------------------------------- +-- DDL for Package FILE_ARCHIVER +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE 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.3.0'; + PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-11 12:00:00'; + PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski'; + + -- Version History (Latest changes first) + VERSION_HISTORY CONSTANT VARCHAR2(4000) := + '3.3.0 (2026-02-11): Added IS_ARCHIVE_ENABLED and IS_KEEP_IN_TRASH columns to A_SOURCE_FILE_CONFIG for selective archiving and config-based TRASH policy. Removed pKeepInTrash parameter (now from config). Added ARCHIVE_ALL batch procedure with 3-level granularity (config/source/all). Added GATHER_TABLE_STAT_ALL batch statistics procedure with 3-level granularity. Added RESTORE_FILE_FROM_TRASH and PURGE_TRASH_FOLDER with 3-level granularity' || CHR(13)||CHR(10) || + '3.2.1 (2026-02-10): Fixed status update - ARCHIVED ? ARCHIVED_AND_TRASHED when moving files to TRASH folder (critical bug fix)' || CHR(13)||CHR(10) || + '3.2.0 (2026-02-06): Added pKeepInTrash parameter (DEFAULT TRUE) to ARCHIVE_TABLE_DATA for TRASH folder retention control - files kept in TRASH subfolder (DATA bucket) by default for safety and compliance' || CHR(13)||CHR(10) || + '3.1.2 (2026-02-06): Fixed missing PARTITION_YEAR/PARTITION_MONTH assignments in UPDATE statement and export query circular dependency (now filters by workflow_start instead of partition fields)' || CHR(13)||CHR(10) || + '3.1.1 (2026-02-06): Fixed ORA-01422 error when DBMS_CLOUD.EXPORT_DATA creates multiple parquet files (parallel execution). Now stores archive directory prefix instead of individual filenames' || CHR(13)||CHR(10) || + '3.1.0 (2026-01-29): Added function overloads for ARCHIVE_TABLE_DATA and GATHER_TABLE_STAT returning SQLCODE for Python library integration' || CHR(13)||CHR(10) || + '3.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 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 + * @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). + * TRASH policy is controlled by A_SOURCE_FILE_CONFIG.IS_KEEP_IN_TRASH column ('Y'=keep in TRASH, 'N'=delete immediately). + **/ + PROCEDURE ARCHIVE_TABLE_DATA ( + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE + ); + + /** + * @name FN_ARCHIVE_TABLE_DATA + * @desc Function wrapper for ARCHIVE_TABLE_DATA procedure. + * Returns SQLCODE for Python library integration. + * Calls the main ARCHIVE_TABLE_DATA procedure and captures execution result. + * TRASH policy is controlled by A_SOURCE_FILE_CONFIG.IS_KEEP_IN_TRASH column ('Y'=keep in TRASH, 'N'=delete immediately). + * @example SELECT FILE_ARCHIVER.FN_ARCHIVE_TABLE_DATA(pSourceFileConfigKey => 123) FROM DUAL; + * @ex_rslt 0 (success) or error code + **/ + FUNCTION FN_ARCHIVE_TABLE_DATA ( + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE + ) 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 FN_GATHER_TABLE_STAT + * @desc Function wrapper 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.FN_GATHER_TABLE_STAT(pSourceFileConfigKey => 123) FROM DUAL; + * @ex_rslt 0 (success) or error code + **/ + FUNCTION FN_GATHER_TABLE_STAT ( + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE + ) RETURN PLS_INTEGER; + + /** + * @name GATHER_TABLE_STAT_ALL + * @desc Multi-level batch statistics gathering procedure with three granularity levels. + * Processes configurations based on IS_ARCHIVE_ENABLED setting (when pOnlyEnabled=TRUE). + * Gathers statistics for external tables and inserts data into A_TABLE_STAT and A_TABLE_STAT_HIST. + * @param pSourceFileConfigKey - (LEVEL 1) Gather stats for specific configuration key (highest priority) + * @param pSourceKey - (LEVEL 2) Gather stats for all tables in source system (e.g., 'LM', 'C2D') (medium priority) + * @param pGatherAll - (LEVEL 3) When TRUE, gather stats for ALL tables across all sources (lowest priority) + * @param pOnlyEnabled - When TRUE (default), only process tables with IS_ARCHIVE_ENABLED='Y' + * @example -- Level 1: CALL FILE_ARCHIVER.GATHER_TABLE_STAT_ALL(pSourceFileConfigKey => 123); + * @example -- Level 2: CALL FILE_ARCHIVER.GATHER_TABLE_STAT_ALL(pSourceKey => 'LM'); + * @example -- Level 3: CALL FILE_ARCHIVER.GATHER_TABLE_STAT_ALL(pGatherAll => TRUE); + * @example -- All tables regardless of IS_ARCHIVE_ENABLED: CALL FILE_ARCHIVER.GATHER_TABLE_STAT_ALL(pGatherAll => TRUE, pOnlyEnabled => FALSE); + **/ + PROCEDURE GATHER_TABLE_STAT_ALL ( + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL, + pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE DEFAULT NULL, + pGatherAll IN BOOLEAN DEFAULT FALSE, + pOnlyEnabled IN BOOLEAN DEFAULT TRUE + ); + + /** + * @name FN_GATHER_TABLE_STAT_ALL + * @desc Function wrapper for GATHER_TABLE_STAT_ALL procedure. + * Returns SQLCODE for Python library integration. + * Calls the main GATHER_TABLE_STAT_ALL procedure and captures execution result. + * @param pSourceFileConfigKey - (LEVEL 1) Gather stats for specific configuration key (highest priority) + * @param pSourceKey - (LEVEL 2) Gather stats for all tables in source system (medium priority) + * @param pGatherAll - (LEVEL 3) When TRUE, gather stats for ALL tables across all sources (lowest priority) + * @param pOnlyEnabled - When TRUE (default), only process tables with IS_ARCHIVE_ENABLED='Y' + * @example SELECT FILE_ARCHIVER.FN_GATHER_TABLE_STAT_ALL(pSourceKey => 'LM') FROM DUAL; + * @ex_rslt 0 (success) or error code + **/ + FUNCTION FN_GATHER_TABLE_STAT_ALL ( + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL, + pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE DEFAULT NULL, + pGatherAll IN BOOLEAN DEFAULT FALSE, + pOnlyEnabled IN BOOLEAN DEFAULT TRUE + ) RETURN PLS_INTEGER; + + /** + * @name ARCHIVE_ALL + * @desc Multi-level batch archival procedure with three granularity levels. + * Only processes configurations where IS_ARCHIVE_ENABLED='Y'. + * TRASH policy for each table is controlled by individual IS_KEEP_IN_TRASH column. + * @param pSourceFileConfigKey - (LEVEL 1) Archive specific configuration key (highest priority) + * @param pSourceKey - (LEVEL 2) Archive all enabled tables for source system (e.g., 'LM', 'C2D') (medium priority) + * @param pArchiveAll - (LEVEL 3) When TRUE, archive ALL enabled tables across all sources (lowest priority) + * @example -- Level 1: CALL FILE_ARCHIVER.ARCHIVE_ALL(pSourceFileConfigKey => 123); + * @example -- Level 2: CALL FILE_ARCHIVER.ARCHIVE_ALL(pSourceKey => 'LM'); + * @example -- Level 3: CALL FILE_ARCHIVER.ARCHIVE_ALL(pArchiveAll => TRUE); + **/ + PROCEDURE ARCHIVE_ALL ( + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL, + pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE DEFAULT NULL, + pArchiveAll IN BOOLEAN DEFAULT FALSE + ); + + /** + * @name FN_ARCHIVE_ALL + * @desc Function wrapper for ARCHIVE_ALL procedure. + * Returns SQLCODE for Python library integration. + * Calls the main ARCHIVE_ALL procedure and captures execution result. + * @param pSourceFileConfigKey - (LEVEL 1) Archive specific configuration key (highest priority) + * @param pSourceKey - (LEVEL 2) Archive all enabled tables for source system (medium priority) + * @param pArchiveAll - (LEVEL 3) When TRUE, archive ALL enabled tables across all sources (lowest priority) + * @example SELECT FILE_ARCHIVER.FN_ARCHIVE_ALL(pSourceKey => 'LM') FROM DUAL; + * @ex_rslt 0 (success) or error code + **/ + FUNCTION FN_ARCHIVE_ALL ( + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL, + pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE DEFAULT NULL, + pArchiveAll IN BOOLEAN DEFAULT FALSE + ) RETURN PLS_INTEGER; + + /** + * @name RESTORE_FILE_FROM_TRASH + * @desc Restores files from TRASH folder back to ODS at three different granularity levels. + * Moves files from TRASH subfolder back to ODS subfolder in DATA bucket. + * Updates status from ARCHIVED_AND_TRASHED to INGESTED and clears archival metadata. + * @param pSourceFileReceivedKey - (LEVEL 3) Specific file to restore by A_SOURCE_FILE_RECEIVED_KEY (highest priority) + * @param pSourceFileConfigKey - (LEVEL 2) Restore all files for specific configuration key (medium priority) + * @param pRestoreAll - (LEVEL 1) When TRUE, restore ALL files with ARCHIVED_AND_TRASHED status (lowest priority) + * @example -- Restore single file: CALL FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pSourceFileReceivedKey => 12345); + * @example -- Restore all files for config: CALL FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pSourceFileConfigKey => 341); + * @example -- Restore all TRASH globally: CALL FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pRestoreAll => TRUE); + **/ + PROCEDURE RESTORE_FILE_FROM_TRASH ( + pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL, + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL, + pRestoreAll IN BOOLEAN DEFAULT FALSE + ); + + /** + * @name RESTORE_FILE_FROM_TRASH + * @desc Function overload for RESTORE_FILE_FROM_TRASH procedure. + * Returns SQLCODE for Python library integration. + * Calls the main RESTORE_FILE_FROM_TRASH procedure and captures execution result. + * @param pSourceFileReceivedKey - (LEVEL 3) Specific file to restore by A_SOURCE_FILE_RECEIVED_KEY (highest priority) + * @param pSourceFileConfigKey - (LEVEL 2) Restore all files for specific configuration key (medium priority) + * @param pRestoreAll - (LEVEL 1) When TRUE, restore ALL files with ARCHIVED_AND_TRASHED status (lowest priority) + * @example SELECT FILE_ARCHIVER.RESTORE_FILE_FROM_TRASH(pSourceFileReceivedKey => 12345) FROM DUAL; + * @ex_rslt 0 (success) or error code + **/ + FUNCTION RESTORE_FILE_FROM_TRASH ( + pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL, + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL, + pRestoreAll IN BOOLEAN DEFAULT FALSE + ) RETURN PLS_INTEGER; + + /** + * @name PURGE_TRASH_FOLDER + * @desc Deletes files from TRASH folder at three different granularity levels. + * Updates status from ARCHIVED_AND_TRASHED to ARCHIVED_AND_PURGED for all affected files. + * WARNING: This operation is irreversible - files are permanently deleted from TRASH. + * @param pSourceFileReceivedKey - (LEVEL 3) Specific file to delete by A_SOURCE_FILE_RECEIVED_KEY (highest priority) + * @param pSourceFileConfigKey - (LEVEL 2) Delete all files for specific configuration key (medium priority) + * @param pPurgeAll - (LEVEL 1) When TRUE, delete ALL files with ARCHIVED_AND_TRASHED status (lowest priority) + * @example -- Delete single file: CALL FILE_ARCHIVER.PURGE_TRASH_FOLDER(pSourceFileReceivedKey => 12345); + * @example -- Delete all files for config: CALL FILE_ARCHIVER.PURGE_TRASH_FOLDER(pSourceFileConfigKey => 341); + * @example -- Delete all TRASH globally: CALL FILE_ARCHIVER.PURGE_TRASH_FOLDER(pPurgeAll => TRUE); + **/ + PROCEDURE PURGE_TRASH_FOLDER ( + pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL, + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL, + pPurgeAll IN BOOLEAN DEFAULT FALSE + ); + + /** + * @name PURGE_TRASH_FOLDER + * @desc Function overload for PURGE_TRASH_FOLDER procedure. + * Returns SQLCODE for Python library integration. + * Calls the main PURGE_TRASH_FOLDER procedure and captures execution result. + * WARNING: This operation is irreversible - files are permanently deleted from TRASH. + * @param pSourceFileReceivedKey - (LEVEL 3) Specific file to delete by A_SOURCE_FILE_RECEIVED_KEY (highest priority) + * @param pSourceFileConfigKey - (LEVEL 2) Delete all files for specific configuration key (medium priority) + * @param pPurgeAll - (LEVEL 1) When TRUE, delete ALL files with ARCHIVED_AND_TRASHED status (lowest priority) + * @example SELECT FILE_ARCHIVER.PURGE_TRASH_FOLDER(pSourceFileReceivedKey => 12345) FROM DUAL; + * @ex_rslt 0 (success) or error code + **/ + FUNCTION PURGE_TRASH_FOLDER ( + pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL, + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE DEFAULT NULL, + pPurgeAll IN BOOLEAN DEFAULT FALSE + ) RETURN PLS_INTEGER; + + --------------------------------------------------------------------------------------------------------------------------- + -- PACKAGE VERSION MANAGEMENT FUNCTIONS + --------------------------------------------------------------------------------------------------------------------------- + + /** + * @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; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_ARCHIVER_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_ARCHIVER_1.sql new file mode 100644 index 0000000..2bb06fd --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_ARCHIVER_1.sql @@ -0,0 +1,1288 @@ +-------------------------------------------------------- +-- DDL for Package Body FILE_ARCHIVER +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE 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.ARCHIVE_THRESHOLD_DAYS; + + -- 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 + ) + 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'; + vKeepInTrash BOOLEAN; -- Derived from config + + 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); + + -- Check if archiving is enabled for this configuration + IF vSourceFileConfig.IS_ARCHIVE_ENABLED = 'N' THEN + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Archiving disabled for this configuration (IS_ARCHIVE_ENABLED=N). Skipping.', 'WARNING', vParameters); + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + RETURN; + END IF; + + -- Get TRASH policy from configuration + vKeepInTrash := (vSourceFileConfig.IS_KEEP_IN_TRASH = 'Y'); + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('TRASH policy from config: IS_KEEP_IN_TRASH=' || vSourceFileConfig.IS_KEEP_IN_TRASH, 'INFO', vParameters); + + 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.ARCHIVE_THRESHOLD_FILES_COUNT then vArchivalTriggeredBy := 'FILES_COUNT'; + elsif vTableStat.OVER_ARCH_THRESOLD_ROW_COUNT >= vSourceFileConfig.ARCHIVE_THRESHOLD_ROWS_COUNT then vArchivalTriggeredBy := vArchivalTriggeredBy||', ROWS_COUNT'; + elsif vTableStat.OVER_ARCH_THRESOLD_SIZE >= vSourceFileConfig.ARCHIVE_THRESHOLD_BYTES_SUM 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')||'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 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 vKeepInTrash 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 (config: IS_KEEP_IN_TRASH=N).','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 (config: IS_KEEP_IN_TRASH=Y, 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.ARCHIVE_THRESHOLD_DAYS), 'NULL')||' as ARCHIVE_THRESHOLD_DAYS + ,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 FN_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 := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( + 'pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey), 'NULL') + )); + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + ---- + ARCHIVE_TABLE_DATA(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 FN_ARCHIVE_TABLE_DATA; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION FN_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 FN_GATHER_TABLE_STAT; + + ---------------------------------------------------------------------------------------------------- + -- BATCH ARCHIVAL PROCEDURES + ---------------------------------------------------------------------------------------------------- + + 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 + ) + IS + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vTablesArchived PLS_INTEGER := 0; + vTablesSkipped PLS_INTEGER := 0; + vTablesFailed PLS_INTEGER := 0; + vProcessingLevel VARCHAR2(50); + BEGIN + vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( + 'pSourceFileConfigKey => '''||nvl(to_char(pSourceFileConfigKey),'NULL')||'''', + 'pSourceKey => '''||nvl(pSourceKey,'NULL')||'''', + 'pArchiveAll => '''||CASE WHEN pArchiveAll THEN 'TRUE' ELSE 'FALSE' END||'''' + )); + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + -- Determine processing level and validate parameters + IF pSourceFileConfigKey IS NOT NULL THEN + vProcessingLevel := 'LEVEL 1: Single Config Key'; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Processing Level 1: pSourceFileConfigKey=' || pSourceFileConfigKey, 'INFO'); + ELSIF pSourceKey IS NOT NULL THEN + vProcessingLevel := 'LEVEL 2: Source Key'; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Processing Level 2: pSourceKey=' || pSourceKey, 'INFO'); + ELSIF pArchiveAll THEN + vProcessingLevel := 'LEVEL 3: Archive All'; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Processing Level 3: Archive All Enabled Tables', 'INFO'); + ELSE + RAISE_APPLICATION_ERROR(-20003, 'No processing level specified. Provide pSourceFileConfigKey, pSourceKey, or set pArchiveAll=TRUE'); + END IF; + + FOR config_rec IN ( + SELECT + A_SOURCE_FILE_CONFIG_KEY, + TABLE_ID, + IS_ARCHIVE_ENABLED, + IS_KEEP_IN_TRASH, + A_SOURCE_KEY + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE SOURCE_FILE_TYPE = 'INPUT' + AND ( + -- Level 1: Specific config key + (pSourceFileConfigKey IS NOT NULL AND A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey) + OR + -- Level 2: All configs for source key + (pSourceFileConfigKey IS NULL AND pSourceKey IS NOT NULL AND A_SOURCE_KEY = pSourceKey) + OR + -- Level 3: All configs when pArchiveAll = TRUE + (pSourceFileConfigKey IS NULL AND pSourceKey IS NULL AND pArchiveAll = TRUE) + ) + ORDER BY A_SOURCE_KEY, A_SOURCE_FILE_CONFIG_KEY + ) LOOP + IF config_rec.IS_ARCHIVE_ENABLED = 'N' THEN + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + 'Skipping table ' || config_rec.TABLE_ID || ' (IS_ARCHIVE_ENABLED=N) [Source: ' || config_rec.A_SOURCE_KEY || ', Config: ' || config_rec.A_SOURCE_FILE_CONFIG_KEY || ']', + 'INFO' + ); + vTablesSkipped := vTablesSkipped + 1; + ELSE + BEGIN + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + 'Archiving table ' || config_rec.TABLE_ID || ' [Source: ' || config_rec.A_SOURCE_KEY || ', Config: ' || config_rec.A_SOURCE_FILE_CONFIG_KEY || ', IS_KEEP_IN_TRASH=' || config_rec.IS_KEEP_IN_TRASH || ']', + 'INFO' + ); + + ARCHIVE_TABLE_DATA(pSourceFileConfigKey => config_rec.A_SOURCE_FILE_CONFIG_KEY); + + vTablesArchived := vTablesArchived + 1; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + 'Successfully archived table ' || config_rec.TABLE_ID, + 'INFO' + ); + EXCEPTION + WHEN OTHERS THEN + vTablesFailed := vTablesFailed + 1; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + 'Failed to archive table ' || config_rec.TABLE_ID || ' [Config: ' || config_rec.A_SOURCE_FILE_CONFIG_KEY || ']: ' || SQLERRM, + 'ERROR' + ); + -- Continue with next table + END; + END IF; + END LOOP; + + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + vProcessingLevel || ' - Batch archival summary: Archived=' || vTablesArchived || ', Skipped=' || vTablesSkipped || ', Failed=' || vTablesFailed, + 'INFO' + ); + 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 ARCHIVE_ALL; + + ---------------------------------------------------------------------------------------------------- + + 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 + 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')||'''', + 'pSourceKey => '''||nvl(pSourceKey,'NULL')||'''', + 'pArchiveAll => '''||CASE WHEN pArchiveAll THEN 'TRUE' ELSE 'FALSE' END||'''' + )); + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + ---- + ARCHIVE_ALL( + pSourceFileConfigKey => pSourceFileConfigKey, + pSourceKey => pSourceKey, + pArchiveAll => pArchiveAll + ); + ---- + 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 FN_ARCHIVE_ALL; + + ---------------------------------------------------------------------------------------------------- + -- BATCH STATISTICS GATHERING PROCEDURES + ---------------------------------------------------------------------------------------------------- + + 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 + ) + IS + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vTablesProcessed PLS_INTEGER := 0; + vTablesSkipped PLS_INTEGER := 0; + vTablesFailed PLS_INTEGER := 0; + vProcessingLevel VARCHAR2(50); + vEnabledFilter VARCHAR2(50); + BEGIN + vParameters := CT_MRDS.ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( + 'pSourceFileConfigKey => '''||nvl(to_char(pSourceFileConfigKey),'NULL')||'''', + 'pSourceKey => '''||nvl(pSourceKey,'NULL')||'''', + 'pGatherAll => '''||CASE WHEN pGatherAll THEN 'TRUE' ELSE 'FALSE' END||'''', + 'pOnlyEnabled => '''||CASE WHEN pOnlyEnabled THEN 'TRUE' ELSE 'FALSE' END||'''' + )); + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + -- Determine processing level and validate parameters + IF pSourceFileConfigKey IS NOT NULL THEN + vProcessingLevel := 'LEVEL 1: Single Config Key'; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Processing Level 1: pSourceFileConfigKey=' || pSourceFileConfigKey, 'INFO'); + ELSIF pSourceKey IS NOT NULL THEN + vProcessingLevel := 'LEVEL 2: Source Key'; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Processing Level 2: pSourceKey=' || pSourceKey, 'INFO'); + ELSIF pGatherAll THEN + vProcessingLevel := 'LEVEL 3: Gather All Statistics'; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Processing Level 3: Gather All Enabled Statistics', 'INFO'); + ELSE + RAISE_APPLICATION_ERROR(-20003, 'No processing level specified. Provide pSourceFileConfigKey, pSourceKey, or set pGatherAll=TRUE'); + END IF; + + -- Set enabled filter info + vEnabledFilter := CASE WHEN pOnlyEnabled THEN 'IS_ARCHIVE_ENABLED=Y only' ELSE 'All tables' END; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Filter mode: ' || vEnabledFilter, 'INFO'); + + FOR config_rec IN ( + SELECT + A_SOURCE_FILE_CONFIG_KEY, + TABLE_ID, + IS_ARCHIVE_ENABLED, + A_SOURCE_KEY + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE SOURCE_FILE_TYPE = 'INPUT' + AND ( + -- Level 1: Specific config key + (pSourceFileConfigKey IS NOT NULL AND A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey) + OR + -- Level 2: All configs for source key + (pSourceFileConfigKey IS NULL AND pSourceKey IS NOT NULL AND A_SOURCE_KEY = pSourceKey) + OR + -- Level 3: All configs when pGatherAll = TRUE + (pSourceFileConfigKey IS NULL AND pSourceKey IS NULL AND pGatherAll = TRUE) + ) + -- Apply IS_ARCHIVE_ENABLED filter if pOnlyEnabled = TRUE + AND (pOnlyEnabled = FALSE OR IS_ARCHIVE_ENABLED = 'Y') + ORDER BY A_SOURCE_KEY, A_SOURCE_FILE_CONFIG_KEY + ) LOOP + IF pOnlyEnabled AND config_rec.IS_ARCHIVE_ENABLED = 'N' THEN + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + 'Skipping table ' || config_rec.TABLE_ID || ' (IS_ARCHIVE_ENABLED=N) [Source: ' || config_rec.A_SOURCE_KEY || ', Config: ' || config_rec.A_SOURCE_FILE_CONFIG_KEY || ']', + 'INFO' + ); + vTablesSkipped := vTablesSkipped + 1; + ELSE + BEGIN + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + 'Gathering statistics for table ' || config_rec.TABLE_ID || ' [Source: ' || config_rec.A_SOURCE_KEY || ', Config: ' || config_rec.A_SOURCE_FILE_CONFIG_KEY || ', IS_ARCHIVE_ENABLED=' || config_rec.IS_ARCHIVE_ENABLED || ']', + 'INFO' + ); + + GATHER_TABLE_STAT(pSourceFileConfigKey => config_rec.A_SOURCE_FILE_CONFIG_KEY); + + vTablesProcessed := vTablesProcessed + 1; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + 'Successfully gathered statistics for table ' || config_rec.TABLE_ID, + 'INFO' + ); + EXCEPTION + WHEN OTHERS THEN + vTablesFailed := vTablesFailed + 1; + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + 'Failed to gather statistics for table ' || config_rec.TABLE_ID || ' [Config: ' || config_rec.A_SOURCE_FILE_CONFIG_KEY || ']: ' || SQLERRM, + 'ERROR' + ); + -- Continue with next table + END; + END IF; + END LOOP; + + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT( + vProcessingLevel || ' - Batch statistics gathering summary: Processed=' || vTablesProcessed || ', Skipped=' || vTablesSkipped || ', Failed=' || vTablesFailed || ' [Filter: ' || vEnabledFilter || ']', + 'INFO' + ); + 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_ALL; + + ---------------------------------------------------------------------------------------------------- + + 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 + 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')||'''', + 'pSourceKey => '''||nvl(pSourceKey,'NULL')||'''', + 'pGatherAll => '''||CASE WHEN pGatherAll THEN 'TRUE' ELSE 'FALSE' END||'''', + 'pOnlyEnabled => '''||CASE WHEN pOnlyEnabled THEN 'TRUE' ELSE 'FALSE' END||'''' + )); + CT_MRDS.ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + ---- + GATHER_TABLE_STAT_ALL( + pSourceFileConfigKey => pSourceFileConfigKey, + pSourceKey => pSourceKey, + pGatherAll => pGatherAll, + pOnlyEnabled => pOnlyEnabled + ); + ---- + 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 FN_GATHER_TABLE_STAT_ALL; + + ---------------------------------------------------------------------------------------------------- + +END; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_MANAGER.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_MANAGER.sql new file mode 100644 index 0000000..f8f426d --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_MANAGER.sql @@ -0,0 +1,730 @@ +-------------------------------------------------------- +-- DDL for Package FILE_MANAGER +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE PACKAGE "CT_MRDS"."FILE_MANAGER" +AUTHID CURRENT_USER +AS + /** + * General comment for package: Please put comments for functions and procedures as shown in below example. + * It is a standard. + * The structure of comment is used by GET_PACKAGE_DOCUMENTATION function + * which returns documentation text for confluence page (to Copy-Paste it). + **/ + + -- Example comment: + /** + * @name EX_PROCEDURE_NAME + * @desc Procedure description + * @example select FILE_MANAGER.EX_PROCEDURE_NAME(pParameter => 129) from dual; + * @ex_rslt Example Result + **/ + + -- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH) + PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.5.1'; + PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2026-02-24 13:35:00'; + PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski'; + + -- Version History (Latest changes first) + VERSION_HISTORY CONSTANT VARCHAR2(4000) := + '3.5.1 (2026-02-24): Fixed TIMESTAMP field syntax in GENERATE_EXTERNAL_TABLE_PARAMS for SQL*Loader compatibility (CHAR(35) DATE_FORMAT TIMESTAMP MASK format)' || CHR(13)||CHR(10) || + '3.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.3.2 (2026-02-20): MARS-828 - Fixed threshold column names in GET_DET_SOURCE_FILE_CONFIG_INFO for MARS-828 compatibility' || CHR(13)||CHR(10) || + '3.3.1 (2025-11-27): MARS-1046 - Fixed ISO 8601 datetime format parsing with milliseconds and timezone (e.g., 2012-03-02T14:16:23.798+01:00)' || CHR(13)||CHR(10) || + '3.3.0 (2025-11-26): MARS-1056 - Fixed VARCHAR2 definitions in GENERATE_EXTERNAL_TABLE_PARAMS to preserve CHAR/BYTE semantics from template tables' || CHR(13)||CHR(10) || + '3.2.1 (2025-11-24): MARS-1049 - Added pEncoding parameter support for CSV character set specification' || CHR(13)||CHR(10) || + '3.2.0 (2025-10-22): Added package versioning system using centralized ENV_MANAGER functions' || CHR(13)||CHR(10) || + '3.1.0 (2025-10-20): Enhanced PROCESS_SOURCE_FILE with 6-step validation workflow' || CHR(13)||CHR(10) || + '3.0.0 (2025-10-15): Separated export procedures into dedicated DATA_EXPORTER package' || CHR(13)||CHR(10) || + '2.5.0 (2025-10-10): Added DELETE_SOURCE_CASCADE for safe configuration removal' || CHR(13)||CHR(10) || + '2.0.0 (2025-09-25): Added official path patterns support (INBOX 3-level, ODS 2-level, ARCHIVE 2-level)' || CHR(13)||CHR(10) || + '1.0.0 (2025-09-01): Initial release with file processing and validation capabilities'; + + TYPE tSourceFileReceived IS RECORD + ( + A_SOURCE_FILE_RECEIVED_KEY CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE, + A_SOURCE_FILE_CONFIG_KEY CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_CONFIG_KEY%TYPE, + SOURCE_FILE_PREFIX_INBOX VARCHAR2(430), + SOURCE_FILE_PREFIX_ODS VARCHAR2(430), + SOURCE_FILE_PREFIX_QUARANTINE VARCHAR2(430), + SOURCE_FILE_PREFIX_ARCHIVE VARCHAR2(430), + SOURCE_FILE_NAME CT_MRDS.A_SOURCE_FILE_RECEIVED.SOURCE_FILE_NAME%TYPE, + RECEPTION_DATE CT_MRDS.A_SOURCE_FILE_RECEIVED.RECEPTION_DATE%TYPE, + PROCESSING_STATUS CT_MRDS.A_SOURCE_FILE_RECEIVED.PROCESSING_STATUS%TYPE, + EXTERNAL_TABLE_NAME CT_MRDS.A_SOURCE_FILE_RECEIVED.EXTERNAL_TABLE_NAME%TYPE + ); + + cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10); + vgSourceFileConfigKey PLS_INTEGER; + vgMsgTmp VARCHAR2(32000); + + + + --------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------- + + /** + * @name GET_SOURCE_FILE_CONFIG + * @desc Get source file type by matching the source file name against source file type naming patterns + * or by specifying the id of a received source file. + * @example ... + * @ex_rslt "CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE" + **/ + FUNCTION GET_SOURCE_FILE_CONFIG(pFileUri IN VARCHAR2 DEFAULT NULL + , pSourceFileReceivedKey IN NUMBER DEFAULT NULL + , pSourceFileConfigKey IN NUMBER DEFAULT NULL) + RETURN CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE; + + + + /** + * @name REGISTER_SOURCE_FILE_RECEIVED + * @desc Register a newly received source file in A_SOURCE_FILE_RECEIVED table. + * This overload automatically determines source file type from the file name. + * It returns the value of A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY column for newly added record. + * @example vSourceFileReceivedKey := FILE_MANAGER.REGISTER_SOURCE_FILE_RECEIVED(pSourceFileReceivedName => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv'); + * @ex_rslt 3245 + **/ + FUNCTION REGISTER_SOURCE_FILE_RECEIVED ( + pSourceFileReceivedName IN VARCHAR2 + ) + RETURN PLS_INTEGER; + + + + /** + * @name REGISTER_SOURCE_FILE_RECEIVED + * @desc Register a new new source file in A_SOURCE_FILE_RECEIVED table based on pSourceFileReceivedName and pSourceFileConfig. + * Then it returns the value of A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY column for newly added record. + * @example vSourceFileReceivedKey := FILE_MANAGER.REGISTER_SOURCE_FILE_RECEIVED( + * pSourceFileReceivedName => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv' + * ,pSourceFileConfig => ...A_SOURCE_FILE_CONFIG%ROWTYPE... ); + * @ex_rslt 3245 + **/ + FUNCTION REGISTER_SOURCE_FILE_RECEIVED ( + pSourceFileReceivedName IN VARCHAR2, + pSourceFileConfig IN CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE + ) + RETURN PLS_INTEGER; + + + + /** + * @name SET_SOURCE_FILE_RECEIVED_STATUS + * @desc Set status of file in A_SOURCE_FILE_RECEIVED table - PROCESSING_STATUS column + * based on A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY + * and provided value of pStatus parameter + * @example exec FILE_MANAGER.SET_SOURCE_FILE_RECEIVED_STATUS(pSourceFileReceivedKey => 377, pStatus => 'READY_FOR_INGESTION'); + **/ + PROCEDURE SET_SOURCE_FILE_RECEIVED_STATUS( + pSourceFileReceivedKey IN PLS_INTEGER, + pStatus IN VARCHAR2 + ); + + + + /** + * @name GET_EXTERNAL_TABLE_COLUMNS + * @desc Function used to get string with all table columns definitions based on pTargetTableTemplate "TEMPLATE TABLE" name. + * It used for creating "EXTERNAL TABLE" using CREATE_EXTERNAL_TABLE procedure. + * @example select FILE_MANAGER.GET_EXTERNAL_TABLE_COLUMNS(pTargetTableTemplate => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER') from dual; + * @ex_rslt "A_KEY" NUMBER(38,0) NOT NULL ENABLE, + * "A_WORKFLOW_HISTORY_KEY" NUMBER(38,0) NOT NULL ENABLE, + * "REV_NUMBER" NUMBER(28,0), + * "REF_DATE" DATE, + * "FREE_TEXT" VARCHAR2(1000 CHAR), + * "MLF_BS_TOTAL" NUMBER(28,10), + * "DF_BS_TOTAL" NUMBER(28,10), + * "MLF_SF_TOTAL" NUMBER(28,10), + * "DF_SF_TOTAL" NUMBER(28,10) + **/ + FUNCTION GET_EXTERNAL_TABLE_COLUMNS ( + pTargetTableTemplate IN VARCHAR2 + ) + RETURN CLOB; + + + + /** + * @name CREATE_EXTERNAL_TABLE + * @desc A wrapper procedure for DBMS_CLOUD.CREATE_EXTERNAL_TABLE which creates External Table + * MARS-1049: Added pEncoding parameter for CSV character set specification + * @param pEncoding - Character set encoding for CSV files (e.g., 'UTF8', 'WE8MSWIN1252') + * If provided, adds CHARACTERSET clause to external table definition + * @example + * begin + * FILE_MANAGER.CREATE_EXTERNAL_TABLE( + * pTableName => 'STANDING_FACILITIES_HEADER', + * pTemplateTableName => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER', + * pPrefix => 'ODS/LM/STANDING_FACILITIES_HEADER/', + * pBucketUri => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/frcnomajoc7v/b/mrds_data_tst/o/', + * pFileName => NULL, + * pDelimiter => ',', + * pEncoding => 'UTF8' + * ); + * end; + **/ + PROCEDURE CREATE_EXTERNAL_TABLE ( + pTableName IN VARCHAR2, + pTemplateTableName IN VARCHAR2, + pPrefix IN VARCHAR2, + pBucketUri IN VARCHAR2 DEFAULT ENV_MANAGER.gvInboxBucketUri, + pFileName IN VARCHAR2 DEFAULT NULL, + pDelimiter IN VARCHAR2 DEFAULT ',', + pEncoding IN VARCHAR2 DEFAULT NULL -- MARS-1049: NOWY PARAMETR + ); + + + + /** + * @name CREATE_EXTERNAL_TABLE + * @desc Creates External Table for single file provided by + * pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY) + * @example exec FILE_MANAGER.CREATE_EXTERNAL_TABLE(pSourceFileReceivedKey => 377);; + **/ + PROCEDURE CREATE_EXTERNAL_TABLE ( + pSourceFileReceivedKey IN NUMBER + ); + + + + /** + * @name VALIDATE_SOURCE_FILE_RECEIVED + * @desc A wrapper procedure for DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE + * It validate External table build upon single file + * provided by pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY) + * @example exec FILE_MANAGER.VALIDATE_SOURCE_FILE_RECEIVED(pSourceFileReceivedKey => 377); + **/ + PROCEDURE VALIDATE_SOURCE_FILE_RECEIVED + ( + pSourceFileReceivedKey IN NUMBER + ); + + + /** + * @name VALIDATE_EXTERNAL_TABLE + * @desc A wrapper function for DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE. + * It validates External Table provided by parameter pTableName. + * It returns: PASSED or FAILED. + * @example + * declare + * vStatus VARCHAR2(100); + * begin + * vStatus := FILE_MANAGER.VALIDATE_EXTERNAL_TABLE(pTableName => 'STANDING_FACILITIES_HEADER'); + * DBMS_OUTPUT.PUT_LINE('vStatus = '||vStatus); + * end; + * + * @ex_rslt FAILED + **/ + FUNCTION VALIDATE_EXTERNAL_TABLE(pTableName IN VARCHAR2) + RETURN VARCHAR2; + + + /** + * @name S_VALIDATE_EXTERNAL_TABLE + * @desc A function which checks if SELECT query reterns any rows. + * It trys to selects External Table provided by parameter pTableName. + * It returns: PASSED or FAILED. + * @example + * declare + * vStatus VARCHAR2(100); + * begin + * vStatus := FILE_MANAGER.S_VALIDATE_EXTERNAL_TABLE(pTableName => 'STANDING_FACILITIES_HEADER'); + * DBMS_OUTPUT.PUT_LINE('vStatus = '||vStatus); + * end; + * + * @ex_rslt PASSED + **/ + FUNCTION S_VALIDATE_EXTERNAL_TABLE(pTableName IN VARCHAR2) + RETURN VARCHAR2; + + + + /** + * @name DROP_EXTERNAL_TABLE + * @desc It drops External Table for single file provided by + * pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY) + * @example exec FILE_MANAGER.DROP_EXTERNAL_TABLE(pSourceFileReceivedKey => 377); + **/ + PROCEDURE DROP_EXTERNAL_TABLE ( + pSourceFileReceivedKey IN NUMBER + ); + + + + /** + * @name COPY_FILE + * @desc It copies file provided by + * pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY) + * into destination provided by pDestination parameter. + * pDestination parameter allowed values are: 'ODS' + * @example exec FILE_MANAGER.COPY_FILE(pSourceFileReceivedKey => 377, pDestination => 'ODS'); + **/ + PROCEDURE COPY_FILE( + pSourceFileReceivedKey IN NUMBER, + pDestination IN VARCHAR2 + ); + + + + + /** + * @name MOVE_FILE + * @desc It moves file provided by + * pSourceFileReceivedKey parameter (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY) + * into destination provided by pDestination parameter. + * pDestination parameter allowed values are: 'ODS', 'QUARANTINE' + * @example exec FILE_MANAGER.MOVE_FILE(pSourceFileReceivedKey => 377, pDestination => 'ODS'); + **/ + PROCEDURE MOVE_FILE( + pSourceFileReceivedKey IN NUMBER, + pDestination IN VARCHAR2 + ); + + + + /** + * @name DELETE_FOLDER_CONTENTS + * @desc It deletes all files from specified folder in the cloud storage. + * The procedure lists all objects in the specified folder prefix and deletes them one by one. + * pBucketArea parameter specifies which bucket to use: 'INBOX', 'DATA', 'ARCHIVE' + * pFolderPrefix parameter specifies the folder path within the bucket (e.g., 'C2D/UC_DISSEM/UC_NMA_DISSEM/') + * @example exec FILE_MANAGER.DELETE_FOLDER_CONTENTS(pBucketArea => 'INBOX', pFolderPrefix => 'C2D/UC_DISSEM/UC_NMA_DISSEM/'); + **/ + PROCEDURE DELETE_FOLDER_CONTENTS( + pBucketArea IN VARCHAR2, + pFolderPrefix IN VARCHAR2 + ); + + + + + /** + * @name PROCESS_SOURCE_FILE + * @desc It process file provided by pSourceFileReceivedName parameter. + * Ubmrella procedure that calls: + * - REGISTER_SOURCE_FILE_RECEIVED; + * - CREATE_EXTERNAL_TABLE; + * - VALIDATE_SOURCE_FILE_RECEIVED; + * - DROP_EXTERNAL_TABLE; + * - MOVE_FILE; + * @example exec FILE_MANAGER.PROCESS_SOURCE_FILE(pSourceFileReceivedName => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv'); + **/ + PROCEDURE PROCESS_SOURCE_FILE(pSourceFileReceivedName IN VARCHAR2) + ; + + + + /** + * @name PROCESS_SOURCE_FILE + * @desc It process file provided by pSourceFileReceivedName parameter and return processing result value. + * It returns (success/failure) => 0 / -(value). + * Ubmrella function that calls PROCESS_SOURCE_FILE procedure. + * @example + * declare + * vResult PLS_INTEGER; + * begin + * vResult := CT_MRDS.FILE_MANAGER.PROCESS_SOURCE_FILE(PSOURCEFILERECEIVEDNAME => 'INBOX/C2D/UC_DISSEM/UC_NMA_DISSEM/UC_NMA_DISSEM-277740.csv'); + * DBMS_OUTPUT.PUT_LINE('vResult = ' || vResult); + * end; + * @ex_rslt 0 + * -20021 + **/ + FUNCTION PROCESS_SOURCE_FILE(pSourceFileReceivedName IN VARCHAR2) + RETURN PLS_INTEGER; + + + + /** + * @name GET_DATE_FORMAT + * @desc Returns date format for specified template table name and column name. + * Date is taken from configuration A_COLUMN_DATE_FORMAT table. + * @example select FILE_MANAGER.GET_DATE_FORMAT( + * pTemplateTableName => 'STANDING_FACILITIES_HEADER', + * pColumnName => 'SNAPSHOT_DATE') + * from dual; + * @ex_rslt DD/MM/YYYY HH24:MI:SS + **/ + FUNCTION GET_DATE_FORMAT( + pTemplateTableName IN VARCHAR2, + pColumnName IN VARCHAR2 + ) RETURN VARCHAR2; + + + + /** + * @name GENERATE_EXTERNAL_TABLE_PARAMS + * @desc It builds two strings: pColumnList and pFieldList for specified Template Table name, by parameter: pTemplateTableName. + * @example + * declare + * vColumnList CLOB; + * vFieldList CLOB; + * begin + * FILE_MANAGER.GENERATE_EXTERNAL_TABLE_PARAMS ( + * pTemplateTableName => 'CT_ET_TEMPLATES.LM_STANDING_FACILITIES_HEADER' + * ,pColumnList => vColumnList + * ,pFieldList => vFieldList + * ); + * DBMS_OUTPUT.PUT_LINE('vColumnList = '||vColumnList); + * DBMS_OUTPUT.PUT_LINE('vFieldList = '||vFieldList); + * end; + * / + **/ + PROCEDURE GENERATE_EXTERNAL_TABLE_PARAMS ( + pTemplateTableName IN VARCHAR2, + pColumnList OUT CLOB, + pFieldList OUT CLOB + ); + + + + + + /** + * @name ADD_SOURCE + * @desc Insert a new record to A_SOURCE table. + * pSourceKey is a PRIMARY KEY value. + **/ + PROCEDURE ADD_SOURCE ( + pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE, + pSourceName IN CT_MRDS.A_SOURCE.SOURCE_NAME%TYPE + ); + + + + /** + * @name DELETE_SOURCE_CASCADE + * @desc Safely deletes a SOURCE specified by pSourceKey parameter from A_SOURCE table and all dependent tables: + * - A_SOURCE_FILE_CONFIG + * - A_SOURCE_FILE_RECEIVED + * - A_COLUMN_DATE_FORMAT (only if template table is not shared with other source systems) + * The procedure checks if template tables are shared before deleting date format configurations. + * If a template table is used by multiple source systems, date formats are preserved. + * @example CALL CT_MRDS.FILE_MANAGER.DELETE_SOURCE_CASCADE(pSourceKey => 'TEST_SYS'); + **/ + PROCEDURE DELETE_SOURCE_CASCADE ( + pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE + ); + + + + /** + * @name GET_CONTAINER_SOURCE_FILE_CONFIG_KEY + * @desc For specified parameter pSourceFileId (A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID) + * it returns A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY for related CONTAINER record. + * @example select FILE_MANAGER.GET_CONTAINER_SOURCE_FILE_CONFIG_KEY( + * pSourceFileId => 'UC_DISSEM') + * from dual; + * @ex_rslt 126 + **/ + FUNCTION GET_CONTAINER_SOURCE_FILE_CONFIG_KEY ( + pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE + ) RETURN PLS_INTEGER; + + + + /** + * @name GET_SOURCE_FILE_CONFIG_KEY + * @desc For specified input parameters, + * it returns A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY. + * @example select FILE_MANAGER.GET_SOURCE_FILE_CONFIG_KEY ( + * pSourceFileType => 'INPUT' + * ,pSourceFileId => 'UC_DISSEM' + * ,pTableId => 'UC_NMA_DISSEM') + * from dual; + * @ex_rslt 126 + **/ + FUNCTION GET_SOURCE_FILE_CONFIG_KEY ( + pSourceFileType IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE%TYPE DEFAULT 'INPUT' + ,pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE + ,pTableId IN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID%TYPE + ) RETURN PLS_INTEGER; + + + + /** + * @name ADD_SOURCE_FILE_CONFIG + * @desc Insert a new record to A_SOURCE_FILE_CONFIG table. + * MARS-1049: Added pEncoding parameter for CSV character set specification. + * @param pEncoding - Character set encoding for CSV files (e.g., 'UTF8', 'WE8MSWIN1252', 'EE8ISO8859P2') + * If NULL, no CHARACTERSET clause is added to external table definitions + * @example CALL CT_MRDS.FILE_MANAGER.ADD_SOURCE_FILE_CONFIG( + * pSourceKey => 'C2D', pSourceFileType => 'INPUT', + * pSourceFileId => 'UC_DISSEM', pTableId => 'METADATA_LOADS', + * pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS', + * pEncoding => 'UTF8' + * ); + **/ + PROCEDURE ADD_SOURCE_FILE_CONFIG ( + pSourceKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_KEY%TYPE + ,pSourceFileType IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE%TYPE + ,pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE + ,pSourceFileDesc IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_DESC%TYPE + ,pSourceFileNamePattern IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_NAME_PATTERN%TYPE + ,pTableId IN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID%TYPE DEFAULT NULL + ,pTemplateTableName IN CT_MRDS.A_SOURCE_FILE_CONFIG.TEMPLATE_TABLE_NAME%TYPE DEFAULT NULL + ,pContainerFileKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.CONTAINER_FILE_KEY%TYPE DEFAULT NULL + ,pEncoding IN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING%TYPE DEFAULT NULL -- MARS-1049: NOWY PARAMETR + ); + + + + /** + * @name ADD_COLUMN_DATE_FORMAT + * @desc Insert a new record to A_COLUMN_DATE_FORMAT table. + **/ + PROCEDURE ADD_COLUMN_DATE_FORMAT ( + pTemplateTableName IN CT_MRDS.A_COLUMN_DATE_FORMAT.TEMPLATE_TABLE_NAME%TYPE + ,pColumnName IN CT_MRDS.A_COLUMN_DATE_FORMAT.COLUMN_NAME%TYPE + ,pDateFormat IN CT_MRDS.A_COLUMN_DATE_FORMAT.DATE_FORMAT%TYPE + ); + + + + /** + * @name GET_BUCKET_URI + * @desc Function used to get string with bucket http url. + * Possible input values for pBucketArea are: 'INBOX', 'ODS', 'DATA', 'ARCHIVE' + * @example select FILE_MANAGER.GET_BUCKET_URI(pBucketArea => 'ODS') from dual; + * @ex_rslt https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/frcnomajoc7v/b/mrds_data_tst/o/ + **/ + FUNCTION GET_BUCKET_URI(pBucketArea VARCHAR2) + RETURN VARCHAR2; + + + + /** + * @name GET_DET_SOURCE_FILE_CONFIG_INFO + * @desc Function returns details about A_SOURCE_FILE_CONFIG record + * for specified pSourceFileConfigKey (A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY). + * If pIncludeContainerInfo is <> 0 it returns additional info about related Container config record (A_SOURCE_FILE_CONFIG) + * If pIncludeColumnFormatInfo is <> 0 it returns additional info about related ColumnFormat config record (A_COLUMN_DATE_FORMAT) + * @example select FILE_MANAGER.GET_DET_SOURCE_FILE_CONFIG_INFO ( + * pSourceFileConfigKey => 128 + * ,pIncludeContainerInfo => 1 + * ,pIncludeColumnFormatInfo => 1 + * ) from dual; + * @ex_rslt + * Details about File Configuration: + * -------------------------------- + * A_SOURCE_FILE_CONFIG_KEY = 128 + * A_SOURCE_KEY = C2D + * ... + * -------------------------------- + * + * Details about related Container Config: + * -------------------------------- + * A_SOURCE_FILE_CONFIG_KEY = 126 + * A_SOURCE_KEY = C2D + * ... + * -------------------------------- + * + * Column Date Format config entries: + * -------------------------------- + * TEMPLATE_TABLE_NAME = CT_ET_TEMPLATES.C2D_UC_MA_DISSEM + * ... + * -------------------------------- + **/ + FUNCTION GET_DET_SOURCE_FILE_CONFIG_INFO ( + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE + ,pIncludeContainerInfo IN PLS_INTEGER DEFAULT 1 + ,pIncludeColumnFormatInfo IN PLS_INTEGER DEFAULT 1 + ) RETURN VARCHAR2; + + + + /** + * @name GET_DET_SOURCE_FILE_RECEIVED_INFO + * @desc Function returns details about A_SOURCE_FILE_RECEIVED record + * for specified pSourceFileReceivedKey (A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY). + * If pIncludeConfigInfo is <> 0 it returns additional info about related Container config record (A_SOURCE_FILE_CONFIG) + * If pIncludeContainerInfo is <> 0 it returns additional info about related Container config record (A_SOURCE_FILE_CONFIG) + * If pIncludeColumnFormatInfo is <> 0 it returns additional info about related ColumnFormat config record (A_COLUMN_DATE_FORMAT) + * @example select FILE_MANAGER.GET_DET_SOURCE_FILE_RECEIVED_INFO ( + * pSourceFileReceivedKey => 377 + * ,pIncludeConfigInfo => 1 + * ,pIncludeContainerInfo => 1 + * ,pIncludeColumnFormatInfo => 1 + * ) from dual; + * + **/ + FUNCTION GET_DET_SOURCE_FILE_RECEIVED_INFO ( + pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE + ,pIncludeConfigInfo IN PLS_INTEGER DEFAULT 1 + ,pIncludeContainerInfo IN PLS_INTEGER DEFAULT 1 + ,pIncludeColumnFormatInfo IN PLS_INTEGER DEFAULT 1 + ) RETURN VARCHAR2; + + + + /** + * @name GET_DET_USER_LOAD_OPERATIONS + * @desc Function returns details from USER_LOAD_OPERATIONS table + * for specified pOperationId. + * @example select FILE_MANAGER.GET_DET_USER_LOAD_OPERATIONS (pOperationId => 3608) from dual; + * @ex_rslt + * Details about USER_LOAD_OPERATIONS where ID = 3608 + * -------------------------------- + * ID = 3608 + * TYPE = VALIDATE + * SID = 31260 + * SERIAL# = 52915 + * START_TIME = 2025-05-20 10.08.24.436983 EUROPE/BELGRADE + * UPDATE_TIME = 2025-05-20 10.08.24.458643 EUROPE/BELGRADE + * STATUS = FAILED + * OWNER_NAME = CT_MRDS + * TABLE_NAME = STANDING_FACILITIES_HEADER + * PARTITION_NAME = + * SUBPARTITION_NAME = + * FILE_URI_LIST = + * ROWS_LOADED = + * LOGFILE_TABLE = VALIDATE$3608_LOG + * BADFILE_TABLE = VALIDATE$3608_BAD + * STATUS_TABLE = + * TEMPEXT_TABLE = + * CREDENTIAL_NAME = + * EXPIRATION_TIME = 2025-05-22 10.08.24.436983000 EUROPE/BELGRADE + * -------------------------------- + **/ + FUNCTION GET_DET_USER_LOAD_OPERATIONS ( + pOperationId PLS_INTEGER + ) RETURN VARCHAR2; + + /** + * @name ANALYZE_VALIDATION_ERRORS + * @desc Wrapper function that analyzes validation errors for a source file using its received key. + * Automatically derives template schema, table name, CSV URI and validation log table + * from file metadata and calls ENV_MANAGER.ANALYZE_VALIDATION_ERRORS. + * @example SELECT FILE_MANAGER.ANALYZE_VALIDATION_ERRORS(63) FROM DUAL; + * @ex_rslt Detailed validation analysis report with column mismatches and solutions + **/ + FUNCTION ANALYZE_VALIDATION_ERRORS( + pSourceFileReceivedKey IN NUMBER + ) RETURN VARCHAR2; + + --------------------------------------------------------------------------------------------------------------------------- + -- EXTERNAL TABLE BATCH OPERATIONS (MARS-1057) + --------------------------------------------------------------------------------------------------------------------------- + + /** + * @name CREATE_EXTERNAL_TABLES_SET + * @desc Creates a complete set of external tables for a single configuration from A_SOURCE_FILE_CONFIG table. + * Automatically generates table names and paths following official path patterns. + * 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 pRecreate - If TRUE, drops existing tables before creating new ones; if FALSE, fails if tables exist + * @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( + * pSourceFileConfigKey => 123, + * pArea => 'INBOX' + * ); + * END; + * + * -- Create all tables with grant preservation + * BEGIN + * 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 ( + pSourceFileConfigKey IN NUMBER, + pRecreate IN BOOLEAN DEFAULT FALSE, + pRestoreGrants IN BOOLEAN DEFAULT TRUE, + pArea IN VARCHAR2 DEFAULT 'ALL' + ); + + /** + * @name CREATE_EXTERNAL_TABLES_BATCH + * @desc Creates external table sets for multiple configurations based on filter criteria. + * Processes only INPUT type files from A_SOURCE_FILE_CONFIG. Creates tables based on pArea parameter + * (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 pSourceFileId - Filter by SOURCE_FILE_ID (NULL = all file types) + * @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 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 + * FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH( + * pSourceKey => 'C2D', + * pArea => 'INBOX' + * ); + * END; + * + * -- Create all external tables for all sources with grant preservation + * BEGIN + * FILE_MANAGER.CREATE_EXTERNAL_TABLES_BATCH( + * pRecreate => TRUE, + * pRestoreGrants => TRUE, + * pArea => 'ALL' + * ); + * END; + * @ex_rslt Returns summary: Total: 10, Processed: 9, Failed: 1 + **/ + 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, + pRestoreGrants IN BOOLEAN DEFAULT TRUE, + pArea IN VARCHAR2 DEFAULT 'ALL' + ); + + --------------------------------------------------------------------------------------------------------------------------- + -- PACKAGE VERSION MANAGEMENT FUNCTIONS + --------------------------------------------------------------------------------------------------------------------------- + + /** + * @name GET_VERSION + * @desc Returns the current version number of the FILE_MANAGER package. + * Uses semantic versioning format (MAJOR.MINOR.PATCH). + * @example SELECT FILE_MANAGER.GET_VERSION() FROM DUAL; + * @ex_rslt 3.2.0 + **/ + FUNCTION GET_VERSION RETURN VARCHAR2; + + /** + * @name GET_BUILD_INFO + * @desc Returns comprehensive build information including version, build date, and author. + * Uses centralized ENV_MANAGER.GET_PACKAGE_VERSION_INFO function. + * @example SELECT FILE_MANAGER.GET_BUILD_INFO() FROM DUAL; + * @ex_rslt Package: FILE_MANAGER + * Version: 3.2.0 + * Build Date: 2025-10-22 16:30:00 + * Author: Grzegorz Michalski + **/ + FUNCTION GET_BUILD_INFO RETURN VARCHAR2; + + /** + * @name GET_VERSION_HISTORY + * @desc Returns complete version history with all releases and changes. + * Uses centralized ENV_MANAGER.FORMAT_VERSION_HISTORY function. + * @example SELECT FILE_MANAGER.GET_VERSION_HISTORY() FROM DUAL; + * @ex_rslt FILE_MANAGER Version History: + * 3.2.0 (2025-10-22): Added package versioning system... + **/ + FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2; + +END; + +/ + + GRANT EXECUTE ON "CT_MRDS"."FILE_MANAGER" TO "ODS"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_MANAGER_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_MANAGER_1.sql new file mode 100644 index 0000000..433a841 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/FILE_MANAGER_1.sql @@ -0,0 +1,2401 @@ +-------------------------------------------------------- +-- DDL for Package Body FILE_MANAGER +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE PACKAGE BODY "CT_MRDS"."FILE_MANAGER" +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 + , pSourceFileReceivedKey IN NUMBER DEFAULT NULL + , pSourceFileConfigKey IN NUMBER DEFAULT NULL) + RETURN CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE + IS + vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( 'pFileUri => '''||nvl(pFileUri,'NULL')||'''' + ,'pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey),'NULL') + ,'pSourceFileConfigKey => '||nvl(to_char(pSourceFileConfigKey),'NULL'))); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + + BEGIN + IF pFileUri IS NOT NULL THEN + SELECT * + INTO vSourceFileConfig + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE REGEXP_LIKE(pFileUri, A_SOURCE_KEY||'/'||SOURCE_FILE_ID||'/'||TABLE_ID||'/'||SOURCE_FILE_NAME_PATTERN); + ELSIF pSourceFileReceivedKey IS NOT NULL THEN + SELECT T.* + INTO vSourceFileConfig + FROM CT_MRDS.A_SOURCE_FILE_CONFIG T, CT_MRDS.A_SOURCE_FILE_RECEIVED R + WHERE T.A_SOURCE_FILE_CONFIG_KEY = R.A_SOURCE_FILE_CONFIG_KEY + AND R.A_SOURCE_FILE_RECEIVED_KEY = pSourceFileReceivedKey; + ELSIF pSourceFileConfigKey IS NOT NULL THEN + SELECT * + INTO vSourceFileConfig + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey; + ELSE + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_EMPTY_FILEURI_AND_RECKEY, ENV_MANAGER.MSG_EMPTY_FILEURI_AND_RECKEY); + END IF; + -- Set global package variable vgSourceFileConfigKey - used in error messages + vgSourceFileConfigKey := vSourceFileConfig.A_SOURCE_FILE_CONFIG_KEY; + EXCEPTION + WHEN ENV_MANAGER.ERR_EMPTY_FILEURI_AND_RECKEY THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_EMPTY_FILEURI_AND_RECKEY, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_EMPTY_FILEURI_AND_RECKEY, ENV_MANAGER.MSG_EMPTY_FILEURI_AND_RECKEY); + + WHEN NO_DATA_FOUND THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_NO_CONFIG_MATCH_FOR_FILEURI, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_NO_CONFIG_MATCH_FOR_FILEURI, ENV_MANAGER.MSG_NO_CONFIG_MATCH_FOR_FILEURI); + + WHEN TOO_MANY_ROWS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_MULTIPLE_MATCH_FOR_SRCFILE, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MULTIPLE_MATCH_FOR_SRCFILE, ENV_MANAGER.MSG_MULTIPLE_MATCH_FOR_SRCFILE); + + WHEN OTHERS THEN + -- Log complete error details including full stack trace and backtrace + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_UNKNOWN, vParameters, 'FILE_MANAGER'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + END; + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters); + RETURN vSourceFileConfig; + + END GET_SOURCE_FILE_CONFIG; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_SOURCE_FILE_RECEIVED_INFO(pSourceFileReceivedKey IN NUMBER DEFAULT NULL) + -- + -- Get source file received info + -- + RETURN tSourceFileReceived + IS + vSourceFileReceived tSourceFileReceived; + vBucket VARCHAR2(400); + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey),'NULL'))); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + BEGIN + SELECT R.A_SOURCE_FILE_RECEIVED_KEY, R.A_SOURCE_FILE_CONFIG_KEY, + 'INBOX'||'/'||T.A_SOURCE_KEY||'/'||T.SOURCE_FILE_ID||'/'||T.TABLE_ID||'/' as SOURCE_FILE_PREFIX_INBOX, + 'ODS'||'/'||T.A_SOURCE_KEY||'/'||T.TABLE_ID||'/' as SOURCE_FILE_PREFIX_ODS, + 'QUARANTINE'||'/'||T.A_SOURCE_KEY||'/'||T.TABLE_ID||'/' as SOURCE_FILE_PREFIX_QUARANTINE, + 'ARCHIVE'||'/'||T.A_SOURCE_KEY||'/'||T.SOURCE_FILE_ID||'/' as SOURCE_FILE_PREFIX_ARCHIVE, + R.SOURCE_FILE_NAME, + R.RECEPTION_DATE, R.PROCESSING_STATUS, R.EXTERNAL_TABLE_NAME + INTO vSourceFileReceived + FROM CT_MRDS.A_SOURCE_FILE_RECEIVED R, CT_MRDS.A_SOURCE_FILE_CONFIG T + WHERE R.A_SOURCE_FILE_CONFIG_KEY = T.A_SOURCE_FILE_CONFIG_KEY + AND A_SOURCE_FILE_RECEIVED_KEY = pSourceFileReceivedKey; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_NO_CONFIG_FOR_RECEIVED_FILE, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_NO_CONFIG_FOR_RECEIVED_FILE, ENV_MANAGER.MSG_NO_CONFIG_FOR_RECEIVED_FILE); + WHEN TOO_MANY_ROWS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_MULTI_CONFIG_FOR_RECEIVED_FILE, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MULTI_CONFIG_FOR_RECEIVED_FILE, ENV_MANAGER.MSG_MULTI_CONFIG_FOR_RECEIVED_FILE); + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + END; + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters); + + RETURN vSourceFileReceived; + + END GET_SOURCE_FILE_RECEIVED_INFO; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION REGISTER_SOURCE_FILE_RECEIVED(pSourceFileReceivedName IN VARCHAR2) + RETURN PLS_INTEGER + -- + -- Register a newly received source file A_SOURCE_FILE_RECEIVED + -- This overload automatically determines source file type from the file name + -- + IS + vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE; + vSourceFileReceivedKey PLS_INTEGER; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedName => '''||nvl(pSourceFileReceivedName, 'NULL')||'''')); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO',vParameters); + + vSourceFileConfig := GET_SOURCE_FILE_CONFIG(pSourceFileReceivedName); + vSourceFileReceivedKey := REGISTER_SOURCE_FILE_RECEIVED(pSourceFileReceivedName, vSourceFileConfig); + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + RETURN vSourceFileReceivedKey; + EXCEPTION + + WHEN ENV_MANAGER.ERR_EMPTY_FILEURI_AND_RECKEY THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_EMPTY_FILEURI_AND_RECKEY, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_EMPTY_FILEURI_AND_RECKEY, ENV_MANAGER.MSG_EMPTY_FILEURI_AND_RECKEY); + + WHEN ENV_MANAGER.ERR_NO_CONFIG_MATCH_FOR_FILEURI THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_NO_CONFIG_MATCH_FOR_FILEURI, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_NO_CONFIG_MATCH_FOR_FILEURI, ENV_MANAGER.MSG_NO_CONFIG_MATCH_FOR_FILEURI); + + WHEN ENV_MANAGER.ERR_FILE_NOT_EXISTS_ON_CLOUD THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_FILE_NOT_EXISTS_ON_CLOUD, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_NOT_EXISTS_ON_CLOUD, ENV_MANAGER.MSG_FILE_NOT_EXISTS_ON_CLOUD); + + WHEN ENV_MANAGER.ERR_FILE_ALREADY_REGISTERED THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_FILE_ALREADY_REGISTERED, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_ALREADY_REGISTERED, ENV_MANAGER.MSG_FILE_ALREADY_REGISTERED); + + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_UNKNOWN, vParameters, 'FILE_MANAGER'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + END REGISTER_SOURCE_FILE_RECEIVED; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION REGISTER_SOURCE_FILE_RECEIVED( + pSourceFileReceivedName IN VARCHAR2 + ,pSourceFileConfig IN CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE) + RETURN PLS_INTEGER + -- + -- Register a newly received source file A_SOURCE_FILE_RECEIVED + -- + IS + vExternalTableName VARCHAR2(200); + vDirName VARCHAR2(1000); + vFileName VARCHAR2(1000); + vChecksum A_SOURCE_FILE_RECEIVED.CHECKSUM%TYPE; + vCreated A_SOURCE_FILE_RECEIVED.CREATED%TYPE; + vBytes A_SOURCE_FILE_RECEIVED.BYTES%TYPE; + vSourceFileReceivedKey PLS_INTEGER; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vRow CT_MRDS.A_SOURCE_FILE_RECEIVED%ROWTYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedName => '''||nvl(pSourceFileReceivedName, 'NULL')||'''' + ,'pSourceFileConfig => '||'tSourceFileConfig record type')); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + vDirName := REGEXP_SUBSTR(pSourceFileReceivedName, '(.*/)(.*)', 1, 1, NULL, 1); + -- Remove prefix from file name + vFileName := REGEXP_SUBSTR(pSourceFileReceivedName,'[^/]*$'); + + ENV_MANAGER.LOG_PROCESS_EVENT('gvCredentialName','DEBUG',ENV_MANAGER.gvCredentialName); + ENV_MANAGER.LOG_PROCESS_EVENT('gvInboxBucketUri','DEBUG',ENV_MANAGER.gvInboxBucketUri); + ENV_MANAGER.LOG_PROCESS_EVENT('vDirName','DEBUG',vDirName); + + SELECT + checksum, created, bytes + INTO + vChecksum, vCreated, vBytes + FROM DBMS_CLOUD.LIST_OBJECTS(ENV_MANAGER.gvCredentialName, + ENV_MANAGER.gvInboxBucketUri || vDirName + ) + WHERE object_name = vFileName + ; + vSourceFileReceivedKey := CT_MRDS.A_SOURCE_FILE_RECEIVED_KEY_SEQ.NEXTVAL; + vExternalTableName := REPLACE( + REGEXP_SUBSTR(pSourceFileConfig.TEMPLATE_TABLE_NAME||'_'||vSourceFileReceivedKey, + '\..*'), + '.',''); + + INSERT INTO CT_MRDS.A_SOURCE_FILE_RECEIVED + (A_SOURCE_FILE_RECEIVED_KEY, A_SOURCE_FILE_CONFIG_KEY, + SOURCE_FILE_NAME, RECEPTION_DATE, + PROCESSING_STATUS, EXTERNAL_TABLE_NAME, + CHECKSUM, CREATED, BYTES) + VALUES (vSourceFileReceivedKey, pSourceFileConfig.A_SOURCE_FILE_CONFIG_KEY, + vFileName, SYSDATE, + 'RECEIVED', vExternalTableName, + vChecksum, vCreated, vBytes); + COMMIT; + + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters); + RETURN vSourceFileReceivedKey; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + vgMsgTmp := ENV_MANAGER.MSG_FILE_NOT_EXISTS_ON_CLOUD + ||cgBL||' '||'File: '||ENV_MANAGER.gvInboxBucketUri || vDirName || vFileName; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_NOT_EXISTS_ON_CLOUD, vgMsgTmp); + + WHEN DUP_VAL_ON_INDEX THEN + select * into vRow + from CT_MRDS.A_SOURCE_FILE_RECEIVED + where CHECKSUM = vChecksum + and CREATED = vCreated + and BYTES = vBytes + ; + vgMsgTmp := ENV_MANAGER.MSG_FILE_ALREADY_REGISTERED + ||cgBL||' '||'Details about existing File: ' + ||cgBL||' '||'-------------------------' + ||cgBL||' '||'A_SOURCE_FILE_RECEIVED_KEY = '||vRow.A_SOURCE_FILE_RECEIVED_KEY + ||cgBL||' '||'A_SOURCE_FILE_CONFIG_KEY = '||vRow.A_SOURCE_FILE_CONFIG_KEY + ||cgBL||' '||'SOURCE_FILE_NAME = '||vRow.SOURCE_FILE_NAME + ||cgBL||' '||'CHECKSUM = '||vRow.CHECKSUM + ||cgBL||' '||'CREATED = '||vRow.CREATED + ||cgBL||' '||'BYTES = '||vRow.BYTES + ||cgBL||' '||'RECEPTION_DATE = '||vRow.RECEPTION_DATE + ||cgBL||' '||'PROCESSING_STATUS = '||vRow.PROCESSING_STATUS + ||cgBL||' '||'EXTERNAL_TABLE_NAME = '||vRow.EXTERNAL_TABLE_NAME + ||cgBL||' '||'-------------------------' + ||cgBL||' '||'There cannot be two files with the same values for (CHECKSUM, CREATED, BYTES)' + ; + + +-- vChecksum, vCreated, vBytes + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_ALREADY_REGISTERED, vgMsgTmp); + + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + + END REGISTER_SOURCE_FILE_RECEIVED; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE SET_SOURCE_FILE_RECEIVED_STATUS(pSourceFileReceivedKey IN PLS_INTEGER, pStatus IN VARCHAR2) + -- + -- Change status of file in the A_SOURCE_FILE_RECEIVED table + -- + IS + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey),'NULL') + ,'pStatus => '''||nvl(pStatus, 'NULL')||'''')); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + UPDATE CT_MRDS.A_SOURCE_FILE_RECEIVED + SET PROCESSING_STATUS=pStatus + WHERE A_SOURCE_FILE_RECEIVED_KEY=pSourceFileReceivedKey; + COMMIT; + ENV_MANAGER.LOG_PROCESS_EVENT('File status changed to '||pStatus,'INFO', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters); + + EXCEPTION + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + + END SET_SOURCE_FILE_RECEIVED_STATUS; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_EXTERNAL_TABLE_COLUMNS(pTargetTableTemplate IN VARCHAR2) + RETURN CLOB + -- + -- Create list of columns for DBMS_CLOUD.CREATE_EXTERNAL_TABLE from existing template table + -- + IS + vColumnList CLOB; + vTableName VARCHAR2(200); + vSchemaName VARCHAR2(200); + BEGIN + vSchemaName := REPLACE(REGEXP_SUBSTR(pTargetTableTemplate,'.*\.'),'.',''); + vTableName := REPLACE(REGEXP_SUBSTR(pTargetTableTemplate,'\..*'),'.',''); + DBMS_METADATA.SET_TRANSFORM_PARAM(-1, 'SQLTERMINATOR', True); + DBMS_METADATA.SET_TRANSFORM_PARAM(-1, 'COLLATION_CLAUSE', 'NEVER'); + DBMS_METADATA.SET_TRANSFORM_PARAM(-1, 'REF_CONSTRAINTS', False); + DBMS_METADATA.SET_TRANSFORM_PARAM(-1, 'STORAGE', False); + DBMS_METADATA.SET_TRANSFORM_PARAM(-1, 'TABLESPACE', False); + DBMS_METADATA.SET_TRANSFORM_PARAM(-1, 'SEGMENT_ATTRIBUTES', False); + vColumnList := RTRIM( + LTRIM( + REGEXP_SUBSTR(DBMS_METADATA.GET_DDL('TABLE', vTableName, vSchemaName),'\(.*\)',1,1,'mn'), + '('), + ')'); + RETURN vColumnList; + END GET_EXTERNAL_TABLE_COLUMNS; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE CREATE_EXTERNAL_TABLE ( + pTableName IN VARCHAR2, + pTemplateTableName IN VARCHAR2, + pPrefix IN VARCHAR2, + pBucketUri IN VARCHAR2 DEFAULT ENV_MANAGER.gvInboxBucketUri, + pFileName IN VARCHAR2 DEFAULT NULL, + pDelimiter IN VARCHAR2 DEFAULT ',', + pEncoding IN VARCHAR2 DEFAULT NULL -- MARS-1049: NEW PARAMETER FOR FILE ENCODING + ) + -- + -- Create external table for a single source file to validate the file structure + -- + IS + vTableName VARCHAR2(200); + vColumnList CLOB; + vFieldList CLOB; + vFormat VARCHAR2(200); + + vPrefix VARCHAR2(200); + vFileName VARCHAR2(1000); + vFileExtension VARCHAR2(200); + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( 'pTableName => '''||nvl(pTableName, 'NULL')||'''' + ,'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||'''' + ,'pPrefix => '''||nvl(pPrefix, 'NULL')||'''' + ,'pBucketUri => '''||nvl(pBucketUri, 'NULL')||'''' + ,'pFileName => '''||nvl(pFileName, 'NULL')||'''' + ,'pDelimiter => '''||nvl(pDelimiter, 'NULL')||'''' + ,'pEncoding => '''||nvl(pEncoding, 'NULL')||'''' -- MARS-1049: NOWY + )); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + -- Strip off leading and trailing slashes from prefix + vPrefix := TRIM(BOTH '/' FROM pPrefix); + + -- Generate column and field list from template table + GENERATE_EXTERNAL_TABLE_PARAMS (pTemplateTableName, vColumnList, vFieldList); + + --vFormat evaluation based on pBucketUri first, then pPrefix + -- Archive bucket should use parquet + implicit partitioning regardless of prefix + IF INSTR(pBucketUri, ENV_MANAGER.gvArchiveBucketName)>0 THEN + vFormat := '{"type": "parquet" + ,"implicit_partition_type": "hive" + ,"implicit_partition_columns":["PARTITION_YEAR","PARTITION_MONTH"]}'; + vColumnList := vColumnList||cgBL||' , "PARTITION_YEAR" varchar2(4)'||cgBL||', "PARTITION_MONTH" varchar2(2)'; + vFieldList := NULL; + vFileExtension := '.parquet'; + + -- For INBOX, ODS, and other ARCHIVE prefixes (not in archive bucket) use CSV + ELSIF SUBSTR(pPrefix,1,5) = 'INBOX' OR SUBSTR(pPrefix,1,3) = 'ODS' + OR SUBSTR(pPrefix,1,7) = 'ARCHIVE' + THEN + -- MARS-1049: Create format with encoding if specified + IF pDelimiter = '|' THEN + IF pEncoding IS NOT NULL AND LENGTH(TRIM(pEncoding)) > 0 THEN + vFormat := json_object( + 'delimiter' VALUE '|', + 'skipheaders' VALUE '1', + 'characterset' VALUE pEncoding + ); + ELSE + vFormat := json_object('delimiter' VALUE '|', 'skipheaders' VALUE '1'); + END IF; + ELSE + IF pEncoding IS NOT NULL AND LENGTH(TRIM(pEncoding)) > 0 THEN + vFormat := json_object( + 'type' VALUE 'CSV', + 'skipheaders' VALUE '1', + 'ignoremissingcolumns' VALUE 'true', + 'characterset' VALUE pEncoding + ); + ELSE + vFormat := json_object('type' VALUE 'CSV', 'skipheaders' VALUE '1', 'ignoremissingcolumns' value 'true'); + END IF; + END IF; + + vFileExtension := '.csv'; + + ELSE + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN_PREFIX, ENV_MANAGER.MSG_UNKNOWN_PREFIX); + END IF; + + -- No filename give: Match all csv files + IF pFileName IS NOT NULL THEN + vFileName := pFileName; + ELSE + vFileName := pBucketUri||vPrefix||'/*'||vFileExtension; + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('pTableName', 'DEBUG', pTableName); + ENV_MANAGER.LOG_PROCESS_EVENT('ENV_MANAGER.vpCredentialName', 'DEBUG', ENV_MANAGER.gvCredentialName); + ENV_MANAGER.LOG_PROCESS_EVENT('vFileName', 'DEBUG', vFileName); + ENV_MANAGER.LOG_PROCESS_EVENT('vColumnList', 'DEBUG', vColumnList); + ENV_MANAGER.LOG_PROCESS_EVENT('vFieldList', 'DEBUG', vFieldList); + ENV_MANAGER.LOG_PROCESS_EVENT('vFormat', 'DEBUG', vFormat); + + -- Pre-validation: Check CSV column count for CSV files only + IF SUBSTR(pPrefix,1,5) = 'INBOX' AND pFileName IS NOT NULL THEN + DECLARE + vCsvFirstLine VARCHAR2(4000); + vCsvColCount NUMBER := 0; + vTemplateColCount NUMBER := 0; + vExcessColumns VARCHAR2(2000); + + -- Get template column count + CURSOR c_template_count IS + SELECT COUNT(*) as col_count + FROM ALL_TAB_COLUMNS + WHERE OWNER = UPPER(REPLACE(REGEXP_SUBSTR(pTemplateTableName,'.*\.'),'.','')) + AND TABLE_NAME = UPPER(REGEXP_REPLACE(pTemplateTableName,'^.*\.','')); + + BEGIN + -- Get template column count + FOR rec IN c_template_count LOOP + vTemplateColCount := rec.col_count; + END LOOP; + + -- Read first line of CSV to count columns + BEGIN + SELECT UTL_RAW.CAST_TO_VARCHAR2( + DBMS_LOB.SUBSTR( + DBMS_CLOUD.GET_OBJECT( + credential_name => ENV_MANAGER.gvCredentialName, + object_uri => pFileName + ), + 4000, 1 + ) + ) INTO vCsvFirstLine FROM DUAL; + + -- Count commas in header line + 1 for total columns + vCsvColCount := REGEXP_COUNT(REGEXP_SUBSTR(vCsvFirstLine, '[^'||chr(10)||']*'), ',') + 1; + + ENV_MANAGER.LOG_PROCESS_EVENT('CSV Column Count: ' || vCsvColCount || ', Template Column Count: ' || vTemplateColCount, 'INFO', vParameters); + + -- Check for excess columns + IF vCsvColCount > vTemplateColCount THEN + vgMsgTmp := ENV_MANAGER.MSG_EXCESS_COLUMNS_DETECTED + ||cgBL||'EXCESS COLUMNS DETECTED!' + ||cgBL||'CSV file has ' || vCsvColCount || ' columns but template expects only ' || vTemplateColCount + ||cgBL||'Excess columns: ' || (vCsvColCount - vTemplateColCount) + ||cgBL||'CSV header: ' || SUBSTR(REGEXP_SUBSTR(vCsvFirstLine, '[^'||chr(10)||']*'), 1, 200) + ||cgBL||'POSSIBLE SOLUTIONS:' + ||cgBL||' 1. Remove excess columns from CSV file before processing' + ||cgBL||' 2. Add excess columns to template table: ' || pTemplateTableName; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_EXCESS_COLUMNS_DETECTED, vgMsgTmp); + END IF; + + EXCEPTION + WHEN ENV_MANAGER.ERR_EXCESS_COLUMNS_DETECTED THEN + RAISE; -- Re-raise the excess columns error + WHEN ENV_MANAGER.ERR_FILE_VALIDATION_FAILED THEN + RAISE; -- Re-raise the validation error + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Warning: Could not perform pre-validation column count check: ' || SQLERRM, 'WARN', vParameters); + -- Continue with normal processing if pre-validation fails + END; + END; + END IF; + + DBMS_CLOUD.CREATE_EXTERNAL_TABLE( + TABLE_NAME => pTableName, + CREDENTIAL_NAME => ENV_MANAGER.gvCredentialName, + FILE_URI_LIST => vFileName, + COLUMN_LIST => vColumnList, + FIELD_LIST => vFieldList, + FORMAT => vFormat + ); + + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters); + + EXCEPTION + WHEN ENV_MANAGER.ERR_EXCESS_COLUMNS_DETECTED THEN + RAISE; -- Re-raise the excess columns error with specific code -20011 + WHEN ENV_MANAGER.ERR_UNKNOWN_PREFIX THEN + vgMsgTmp := ENV_MANAGER.MSG_UNKNOWN_PREFIX || ': ' || pPrefix; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN_PREFIX, vgMsgTmp); + WHEN ENV_MANAGER.ERR_MISSING_COLUMN_DATE_FORMAT THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_MISSING_COLUMN_DATE_FORMAT, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MISSING_COLUMN_DATE_FORMAT, ENV_MANAGER.MSG_MISSING_COLUMN_DATE_FORMAT); + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + + END CREATE_EXTERNAL_TABLE; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE CREATE_EXTERNAL_TABLE(pSourceFileReceivedKey IN NUMBER) + -- + -- Create external table for a single source file to validate the file structure + -- + IS + vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE; + vSourceFileReceived tSourceFileReceived; + vTableName VARCHAR2(200); + vFileName VARCHAR2(1000); + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey), 'NULL'))); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + vSourceFileConfig := GET_SOURCE_FILE_CONFIG(pSourceFileReceivedKey => pSourceFileReceivedKey); + vSourceFileReceived := GET_SOURCE_FILE_RECEIVED_INFO(pSourceFileReceivedKey); + vTableName := vSourceFileConfig.TEMPLATE_TABLE_NAME; + + vFileName := ENV_MANAGER.gvInboxBucketUri ||vSourceFileReceived.SOURCE_FILE_PREFIX_INBOX||vSourceFileReceived.SOURCE_FILE_NAME; + + CREATE_EXTERNAL_TABLE( + pTableName => vSourceFileReceived.EXTERNAL_TABLE_NAME, + pTemplateTableName => vSourceFileConfig.TEMPLATE_TABLE_NAME, + pPrefix => vSourceFileReceived.SOURCE_FILE_PREFIX_INBOX, + pBucketUri => ENV_MANAGER.gvInboxBucketUri, + pFileName => vFileName, + pDelimiter => ',', + pEncoding => vSourceFileConfig.ENCODING -- MARS-1049: NOWY PARAMETR + ); + + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + + END CREATE_EXTERNAL_TABLE; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE VALIDATE_SOURCE_FILE_RECEIVED(pSourceFileReceivedKey IN NUMBER) + -- + -- Check the structure of the received file using DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE + -- + IS + vSourceFileReceived tSourceFileReceived; + vOperationId NUMBER := -1; + vBadfileTable USER_LOAD_OPERATIONS.BADFILE_TABLE%TYPE; + vStatus USER_LOAD_OPERATIONS.STATUS%TYPE; + vErrors NUMBER := 0; + vNumRows NUMBER := 0; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey), 'NULL'))); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + vSourceFileReceived := GET_SOURCE_FILE_RECEIVED_INFO(pSourceFileReceivedKey); + ENV_MANAGER.LOG_PROCESS_EVENT('vSourceFileReceived.EXTERNAL_TABLE_NAME: '||vSourceFileReceived.EXTERNAL_TABLE_NAME,'DEBUG', vParameters); + BEGIN + DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE(vSourceFileReceived.EXTERNAL_TABLE_NAME, vOperationId); + EXCEPTION + WHEN OTHERS THEN + -- Log complete error details including full stack trace and backtrace + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_FILE_VALIDATION_FAILED, vParameters, 'FILE_MANAGER'); + + -- Call detailed validation error analysis and log the results + DECLARE + vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE; + vValidationLogTable VARCHAR2(200); + vTemplateSchema VARCHAR2(200); + vTemplateTable VARCHAR2(200); + vCsvFileUri VARCHAR2(2000); + vAnalysisResult VARCHAR2(32000); + vFailedOperationId NUMBER; + BEGIN + -- Get source file configuration + vSourceFileConfig := GET_SOURCE_FILE_CONFIG(pSourceFileReceivedKey => pSourceFileReceivedKey); + + -- Extract template schema and table from template table name + vTemplateSchema := REPLACE(REGEXP_SUBSTR(vSourceFileConfig.TEMPLATE_TABLE_NAME,'.*\.'),'.',''); + vTemplateTable := REPLACE(REGEXP_SUBSTR(vSourceFileConfig.TEMPLATE_TABLE_NAME,'\..*'),'.',''); + + -- Construct CSV file URI + vCsvFileUri := ENV_MANAGER.gvInboxBucketUri || vSourceFileReceived.SOURCE_FILE_PREFIX_INBOX || vSourceFileReceived.SOURCE_FILE_NAME; + + -- Find the failed validation operation ID + SELECT MAX(ID) INTO vFailedOperationId + FROM USER_LOAD_OPERATIONS + WHERE TABLE_NAME = vSourceFileReceived.EXTERNAL_TABLE_NAME + AND TYPE = 'VALIDATE' + AND STATUS != 'COMPLETED'; + + -- Get validation log table name + IF vFailedOperationId IS NOT NULL THEN + SELECT LOGFILE_TABLE INTO vValidationLogTable + FROM USER_LOAD_OPERATIONS + WHERE ID = vFailedOperationId; + + -- Call detailed error analysis + vAnalysisResult := ENV_MANAGER.ANALYZE_VALIDATION_ERRORS( + pValidationLogTable => vValidationLogTable, + pTemplateSchema => vTemplateSchema, + pTemplateTable => vTemplateTable, + pCsvFileUri => vCsvFileUri + ); + + -- Log detailed analysis results + ENV_MANAGER.LOG_PROCESS_EVENT('DETAILED VALIDATION ERROR ANALYSIS:', 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(vAnalysisResult, 'ERROR', vParameters); + END IF; + EXCEPTION + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Error during validation analysis: ' || SQLERRM, 'ERROR', vParameters); + END; + + MOVE_FILE(pSourceFileReceivedKey => pSourceFileReceivedKey, pDestination => 'QUARANTINE'); + -- Ensure the status change is committed before raising exception + COMMIT; + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_VALIDATION_FAILED, ENV_MANAGER.MSG_FILE_VALIDATION_FAILED); + END; + ENV_MANAGER.LOG_PROCESS_EVENT('vOperationId of validation: '||vOperationId,'DEBUG', vParameters); + IF vOperationId = -1 + THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_DIDNT_GET_LOAD_OPERATION_ID, ENV_MANAGER.MSG_DIDNT_GET_LOAD_OPERATION_ID); + END IF; + + SELECT BADFILE_TABLE, ROWS_LOADED, STATUS + INTO vBadfileTable, vNumRows, vStatus + FROM USER_LOAD_OPERATIONS + WHERE ID = vOperationId; + +-- DBMS_OUTPUT.PUT_LINE(vStatus); + SET_SOURCE_FILE_RECEIVED_STATUS(pSourceFileReceivedKey => pSourceFileReceivedKey, pStatus => 'VALIDATED'); + ENV_MANAGER.LOG_PROCESS_EVENT('File status changed to VALIDATED','DEBUG', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + + EXCEPTION + WHEN ENV_MANAGER.ERR_DIDNT_GET_LOAD_OPERATION_ID THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_DIDNT_GET_LOAD_OPERATION_ID, 'ERROR', vParameters); + SET_SOURCE_FILE_RECEIVED_STATUS(pSourceFileReceivedKey => pSourceFileReceivedKey, pStatus => 'VALIDATION_FAILED'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_DIDNT_GET_LOAD_OPERATION_ID, ENV_MANAGER.MSG_DIDNT_GET_LOAD_OPERATION_ID); + + WHEN ENV_MANAGER.ERR_FILE_VALIDATION_FAILED THEN + vgMsgTmp := ENV_MANAGER.MSG_FILE_VALIDATION_FAILED; + ENV_MANAGER.LOG_PROCESS_ERROR(vgMsgTmp, vParameters, 'FILE_MANAGER'); + SET_SOURCE_FILE_RECEIVED_STATUS(pSourceFileReceivedKey => pSourceFileReceivedKey, pStatus => 'VALIDATION_FAILED'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_VALIDATION_FAILED, vgMsgTmp); + + WHEN OTHERS THEN + IF SQLCODE = -20404 THEN + vgMsgTmp := ENV_MANAGER.MSG_FILE_NOT_FOUND_ON_CLOUD||cgBL||SQLERRM; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_NOT_FOUND_ON_CLOUD, vgMsgTmp); + + ELSIF SQLCODE = -20003 THEN + execute immediate 'select LISTAGG(record, '''||cgBL||''') from (select * from '||REGEXP_SUBSTR(SQLERRM, '"([^"]+)"."([^"]+)"')||' order by rownum desc) where rownum <=2' + into vgMsgTmp; + vgMsgTmp := ENV_MANAGER.MSG_FILE_VALIDATION_FAILED||cgBL||SQLERRM||cgBL||vgMsgTmp; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_VALIDATION_FAILED, vgMsgTmp); +-- ELSIF SQLCODE = -20000 THEN + -- TO_DO Add additional info about current config + -- ENV_MANAGER.MSG_FILE_VALIDATION_FAILED := ENV_MANAGER.MSG_FILE_VALIDATION_FAILED||cgBL||SQLERRM||cgBL||FILE_MANAGER.OUTPUT_SOURCE_FILE_CONFIG_INFO( ..config key value.. ); +-- dbms_output.put_line(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); +-- ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_WRONG_DATE_TIMESTAMP_FORMAT, 'ERROR', vParameters); +-- ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); +-- RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_WRONG_DATE_TIMESTAMP_FORMAT, ENV_MANAGER.MSG_WRONG_DATE_TIMESTAMP_FORMAT); + + ELSE + -- Log complete error details including full stack trace and backtrace + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_UNKNOWN, vParameters, 'FILE_MANAGER'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + END IF; + END VALIDATE_SOURCE_FILE_RECEIVED; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION VALIDATE_EXTERNAL_TABLE(pTableName IN VARCHAR2) + RETURN VARCHAR2 + -- + -- wrapper for DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE + -- + IS + vOperationId NUMBER := -1; + vBadfileTable USER_LOAD_OPERATIONS.BADFILE_TABLE%TYPE; + vLogfileTable USER_LOAD_OPERATIONS.LOGFILE_TABLE%TYPE; + vStatus USER_LOAD_OPERATIONS.STATUS%TYPE; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vDetails clob; + TYPE TCURSOR is REF CURSOR; + vCursor TCURSOR; + vQuery VARCHAR2(1000); + vRecord VARCHAR2(10000); + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pTableName => '''||nvl(pTableName, 'NULL')||'''')); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + DBMS_CLOUD.VALIDATE_EXTERNAL_TABLE(pTableName, vOperationId); + ENV_MANAGER.LOG_PROCESS_EVENT('vOperationId of validation: '||vOperationId,'DEBUG', vParameters); + IF vOperationId = -1 + THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_DIDNT_GET_LOAD_OPERATION_ID, ENV_MANAGER.MSG_DIDNT_GET_LOAD_OPERATION_ID); + END IF; + + SELECT decode(STATUS, 'COMPLETED', 'PASSED', STATUS), LOGFILE_TABLE, BADFILE_TABLE + INTO vStatus, vLogfileTable, vBadfileTable + FROM USER_LOAD_OPERATIONS + WHERE ID = vOperationId; + + RETURN vStatus; + EXCEPTION + WHEN ENV_MANAGER.ERR_DIDNT_GET_LOAD_OPERATION_ID THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_DIDNT_GET_LOAD_OPERATION_ID, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_DIDNT_GET_LOAD_OPERATION_ID, ENV_MANAGER.MSG_DIDNT_GET_LOAD_OPERATION_ID); + + WHEN OTHERS THEN + SELECT decode(STATUS, 'COMPLETED', 'PASSED', STATUS), LOGFILE_TABLE, BADFILE_TABLE + INTO vStatus, vLogfileTable, vBadfileTable + FROM USER_LOAD_OPERATIONS + WHERE ID = vOperationId; + vQuery := 'select record from ( + select + nvl(l.record,''----------------------------------------------------'') as record + ,rownum as lp + ,max(case when nvl(instr(l.record, ''error'' ),0) > 0 then rownum else 0 end) over (partition by 1) as ENV_MANAGER.ERR_row + from '||vLogfileTable||' l + ) + where lp >= ENV_MANAGER.ERR_row + order by rownum'; + + vDetails := vStatus||cgBL||'----------------------------------------------------'||cgBL; + + OPEN vCursor for vQuery; + loop + fetch vCursor into vRecord; + EXIT WHEN vCursor%NOTFOUND; + vDetails := vDetails ||vRecord ||cgBL; +-- for i in loop +-- vDetails := vDetails ||i.record ||cgBL; + end loop; + CLOSE vCursor; + vDetails := vDetails||'More details can be found in below tables:'||cgBL|| + ' SELECT * FROM USER_LOAD_OPERATIONS WHERE ID = '||vOperationId||';'||cgBL|| + ' SELECT * FROM '||vLogfileTable||';'||cgBL|| + ' SELECT * FROM '||vBadfileTable||';' + ; + + RETURN vDetails; + + END VALIDATE_EXTERNAL_TABLE; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION S_VALIDATE_EXTERNAL_TABLE(pTableName IN VARCHAR2) + RETURN VARCHAR2 + -- + -- Simple + -- + IS + vCount PLS_INTEGER; + BEGIN + execute immediate 'select count(1) from '||pTableName into vCount; + IF vCount >= 0 + THEN + RETURN 'PASSED'; + END IF; + + RETURN 'FAILED'; + EXCEPTION + WHEN OTHERS THEN + RETURN 'FAILED'; + END S_VALIDATE_EXTERNAL_TABLE; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE DROP_EXTERNAL_TABLE(pSourceFileReceivedKey IN NUMBER) + -- + -- Drop external table created to validate the file structure + -- + IS + vSourceFileReceived tSourceFileReceived; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedKey => '||nvl(to_char(pSourceFileReceivedKey), 'NULL'))); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + vSourceFileReceived := GET_SOURCE_FILE_RECEIVED_INFO(pSourceFileReceivedKey); + EXECUTE IMMEDIATE 'DROP TABLE '||vSourceFileReceived.EXTERNAL_TABLE_NAME; + + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + EXCEPTION + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + END DROP_EXTERNAL_TABLE; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE COPY_FILE(pSourceFileReceivedKey IN NUMBER, pDestination IN VARCHAR2) + -- + -- Possible pDestination values are: 'ODS' or 'ARCHIVE' + -- + IS + vSourceFileReceivedInfo tSourceFileReceived; + vSourceObject VARCHAR2(2000); + vTargetObject VARCHAR2(2000); + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; +-- vStatus VARCHAR2(20); + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedKey => ' ||nvl(to_char(pSourceFileReceivedKey), 'NULL'), + 'pDestination => '''||nvl(pDestination, 'NULL')||'''')); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + vSourceFileReceivedInfo := GET_SOURCE_FILE_RECEIVED_INFO(pSourceFileReceivedKey); + + IF pDestination = 'ODS' THEN + vSourceObject := ENV_MANAGER.gvInboxBucketUri||vSourceFileReceivedInfo.SOURCE_FILE_PREFIX_INBOX ||vSourceFileReceivedInfo.SOURCE_FILE_NAME; + vTargetObject := ENV_MANAGER.gvDataBucketUri||vSourceFileReceivedInfo.SOURCE_FILE_PREFIX_ODS ||vSourceFileReceivedInfo.SOURCE_FILE_NAME; + ELSE + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_WRONG_DESTINATION_PARAM, ENV_MANAGER.MSG_WRONG_DESTINATION_PARAM); + END IF; + + DBMS_CLOUD.COPY_OBJECT(source_credential_name => ENV_MANAGER.gvCredentialName, + source_object_uri => vSourceObject, + target_object_uri => vTargetObject, + target_credential_name => ENV_MANAGER.gvCredentialName + ); + ENV_MANAGER.LOG_PROCESS_EVENT('File copied to '||pDestination||' target location','DEBUG', vTargetObject); + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + + EXCEPTION + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + END COPY_FILE; + + ---------------------------------------------------------------------------------------------------- + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE MOVE_FILE(pSourceFileReceivedKey IN NUMBER, pDestination IN VARCHAR2) + -- + -- Possible pDestination values are: 'ODS' or 'ARCHIVE' + -- + IS + vSourceFileReceivedInfo tSourceFileReceived; + vSourceObject VARCHAR2(2000); + vTargetObject VARCHAR2(2000); + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vStatus VARCHAR2(20); + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedKey => ' ||nvl(to_char(pSourceFileReceivedKey), 'NULL'), + 'pDestination => '''||nvl(pDestination, 'NULL')||'''')); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + + vSourceFileReceivedInfo := GET_SOURCE_FILE_RECEIVED_INFO(pSourceFileReceivedKey); + + IF pDestination = 'ODS' THEN + vSourceObject := ENV_MANAGER.gvInboxBucketUri||vSourceFileReceivedInfo.SOURCE_FILE_PREFIX_INBOX ||vSourceFileReceivedInfo.SOURCE_FILE_NAME; + vTargetObject := ENV_MANAGER.gvDataBucketUri||vSourceFileReceivedInfo.SOURCE_FILE_PREFIX_ODS ||vSourceFileReceivedInfo.SOURCE_FILE_NAME; + vStatus := 'READY_FOR_INGESTION'; + ELSIF pDestination = 'QUARANTINE' THEN + vSourceObject := ENV_MANAGER.gvInboxBucketUri ||vSourceFileReceivedInfo.SOURCE_FILE_PREFIX_INBOX ||vSourceFileReceivedInfo.SOURCE_FILE_NAME; + vTargetObject := ENV_MANAGER.gvInboxBucketUri||vSourceFileReceivedInfo.SOURCE_FILE_PREFIX_QUARANTINE||vSourceFileReceivedInfo.SOURCE_FILE_NAME; + vStatus := 'VALIDATION_FAILED'; + ELSE + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_WRONG_DESTINATION_PARAM, ENV_MANAGER.MSG_WRONG_DESTINATION_PARAM); + END IF; + + DBMS_CLOUD.MOVE_OBJECT(source_credential_name => ENV_MANAGER.gvCredentialName, + source_object_uri => vSourceObject, + target_object_uri => vTargetObject, + target_credential_name => ENV_MANAGER.gvCredentialName + ); + ENV_MANAGER.LOG_PROCESS_EVENT('File moved to '||pDestination||' target location','DEBUG', vTargetObject); + SET_SOURCE_FILE_RECEIVED_STATUS(pSourceFileReceivedKey => pSourceFileReceivedKey, pStatus => vStatus); + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + + EXCEPTION + WHEN ENV_MANAGER.ERR_WRONG_DESTINATION_PARAM THEN + ENV_MANAGER.MSG_WRONG_DESTINATION_PARAM := ENV_MANAGER.MSG_WRONG_DESTINATION_PARAM + ||cgBL||' '||'Possible parameters are: ''ODS'' or ''ARCHIVE''' + ||cgBL||' '||'Provided destination parameter: '''||pDestination||''''; + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_WRONG_DESTINATION_PARAM, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_WRONG_DESTINATION_PARAM, ENV_MANAGER.MSG_WRONG_DESTINATION_PARAM); + WHEN ENV_MANAGER.ERR_NO_CONFIG_FOR_RECEIVED_FILE THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_NO_CONFIG_FOR_RECEIVED_FILE, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_NO_CONFIG_FOR_RECEIVED_FILE, ENV_MANAGER.MSG_NO_CONFIG_FOR_RECEIVED_FILE); + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + END MOVE_FILE; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE DELETE_FOLDER_CONTENTS(pBucketArea IN VARCHAR2, pFolderPrefix IN VARCHAR2) + -- + -- Delete all files from specified folder in cloud storage + -- pBucketArea: 'INBOX', 'DATA', 'ARCHIVE' + -- pFolderPrefix: folder path within bucket (e.g., 'C2D/UC_DISSEM/UC_NMA_DISSEM/') + -- + IS + vBucketUri VARCHAR2(2000); + vFolderUri VARCHAR2(2000); + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vFilesDeleted PLS_INTEGER := 0; + vObjectName VARCHAR2(4000); + vFullObjectUri VARCHAR2(4000); + + -- Cursor to list all objects in the folder + CURSOR c_objects IS + SELECT object_name + FROM TABLE(DBMS_CLOUD.LIST_OBJECTS( + credential_name => ENV_MANAGER.gvCredentialName, + location_uri => vBucketUri + )) + WHERE object_name IS NOT NULL + AND object_name LIKE pFolderPrefix || '%'; + + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( + 'pBucketArea => '''||nvl(pBucketArea, 'NULL')||'''', + 'pFolderPrefix => '''||nvl(pFolderPrefix, 'NULL')||'''' + )); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + -- Get bucket URI based on bucket area + vBucketUri := GET_BUCKET_URI(pBucketArea); + + ENV_MANAGER.LOG_PROCESS_EVENT('Listing objects in bucket with prefix: ' || pFolderPrefix, 'DEBUG', vBucketUri); + + -- List and delete all objects in the folder + FOR obj_rec IN c_objects LOOP + vObjectName := obj_rec.object_name; + vFullObjectUri := vBucketUri || vObjectName; + + BEGIN + ENV_MANAGER.LOG_PROCESS_EVENT('Deleting object', 'DEBUG', vFullObjectUri); + + DBMS_CLOUD.DELETE_OBJECT( + credential_name => ENV_MANAGER.gvCredentialName, + object_uri => vFullObjectUri + ); + + vFilesDeleted := vFilesDeleted + 1; + ENV_MANAGER.LOG_PROCESS_EVENT('Object deleted successfully', 'DEBUG', vObjectName); + + EXCEPTION + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Error deleting object: ' || vObjectName || ' - ' || SQLERRM, 'ERROR', vParameters); + -- Continue with next file instead of stopping the whole process + END; + END LOOP; + + ENV_MANAGER.LOG_PROCESS_EVENT('Total files deleted: ' || vFilesDeleted, 'INFO', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO', vParameters); + + EXCEPTION + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Error in DELETE_FOLDER_CONTENTS: ' || SQLERRM, 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + END DELETE_FOLDER_CONTENTS; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE PROCESS_SOURCE_FILE(pSourceFileReceivedName IN VARCHAR2) + -- + -- Ubmrella procedure that calls + -- - REGISTER_SOURCE_FILE_RECEIVED + -- - CREATE_EXTERNAL_TABLE + -- - VALIDATE_SOURCE_FILE_RECEIVED + -- - DROP_EXTERNAL_TABLE + -- - MOVE_FILE + IS + vSourceFileId NUMBER; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedName => '||nvl(pSourceFileReceivedName, 'NULL'))); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + ---- + vSourceFileId := REGISTER_SOURCE_FILE_RECEIVED(pSourceFileReceivedName); + CREATE_EXTERNAL_TABLE(vSourceFileId); + VALIDATE_SOURCE_FILE_RECEIVED(vSourceFileId); + DROP_EXTERNAL_TABLE(vSourceFileId); +-- COPY_FILE(vSourceFileId, 'ODS'); + MOVE_FILE(vSourceFileId, 'ODS'); + SET_SOURCE_FILE_RECEIVED_STATUS(pSourceFileReceivedKey => vSourceFileId, pStatus => 'READY_FOR_INGESTION'); + + + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + + EXCEPTION + -- -20001 + WHEN ENV_MANAGER.ERR_EMPTY_FILEURI_AND_RECKEY THEN + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_EMPTY_FILEURI_AND_RECKEY, vParameters, 'FILE_MANAGER'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_EMPTY_FILEURI_AND_RECKEY, ENV_MANAGER.MSG_EMPTY_FILEURI_AND_RECKEY); + -- -20002 + WHEN ENV_MANAGER.ERR_NO_CONFIG_MATCH_FOR_FILEURI THEN + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_NO_CONFIG_MATCH_FOR_FILEURI, vParameters, 'FILE_MANAGER'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_NO_CONFIG_MATCH_FOR_FILEURI, ENV_MANAGER.MSG_NO_CONFIG_MATCH_FOR_FILEURI); + -- -20003 + WHEN ENV_MANAGER.ERR_MULTIPLE_MATCH_FOR_SRCFILE THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_MULTIPLE_MATCH_FOR_SRCFILE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MULTIPLE_MATCH_FOR_SRCFILE, ENV_MANAGER.MSG_MULTIPLE_MATCH_FOR_SRCFILE); + -- -20004 + WHEN ENV_MANAGER.ERR_MISSING_COLUMN_DATE_FORMAT THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_MISSING_COLUMN_DATE_FORMAT), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MISSING_COLUMN_DATE_FORMAT, ENV_MANAGER.MSG_MISSING_COLUMN_DATE_FORMAT); + -- -20005 + WHEN ENV_MANAGER.ERR_MULTIPLE_COLUMN_DATE_FORMAT THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_MULTIPLE_COLUMN_DATE_FORMAT), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MULTIPLE_COLUMN_DATE_FORMAT, ENV_MANAGER.MSG_MULTIPLE_COLUMN_DATE_FORMAT); + -- -20006 + WHEN ENV_MANAGER.ERR_DIDNT_GET_LOAD_OPERATION_ID THEN + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_DIDNT_GET_LOAD_OPERATION_ID, vParameters, 'FILE_MANAGER'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_DIDNT_GET_LOAD_OPERATION_ID, ENV_MANAGER.MSG_DIDNT_GET_LOAD_OPERATION_ID); + -- -20007 + WHEN ENV_MANAGER.ERR_NO_CONFIG_FOR_RECEIVED_FILE THEN + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_NO_CONFIG_FOR_RECEIVED_FILE, vParameters, 'FILE_MANAGER'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_NO_CONFIG_FOR_RECEIVED_FILE, ENV_MANAGER.MSG_NO_CONFIG_FOR_RECEIVED_FILE); + -- -20008 + WHEN ENV_MANAGER.ERR_MULTI_CONFIG_FOR_RECEIVED_FILE THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_MULTI_CONFIG_FOR_RECEIVED_FILE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MULTI_CONFIG_FOR_RECEIVED_FILE, ENV_MANAGER.MSG_MULTI_CONFIG_FOR_RECEIVED_FILE); + -- -20009 + WHEN ENV_MANAGER.ERR_FILE_NOT_FOUND_ON_CLOUD THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_FILE_NOT_FOUND_ON_CLOUD), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_NOT_FOUND_ON_CLOUD, ENV_MANAGER.MSG_FILE_NOT_FOUND_ON_CLOUD); + -- -20010 + WHEN ENV_MANAGER.ERR_FILE_VALIDATION_FAILED THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_FILE_VALIDATION_FAILED), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_VALIDATION_FAILED, ENV_MANAGER.MSG_FILE_VALIDATION_FAILED); + -- -20011 + WHEN ENV_MANAGER.ERR_NO_CONFIG_MATCH THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_NO_CONFIG_MATCH), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_NO_CONFIG_MATCH, ENV_MANAGER.MSG_NO_CONFIG_MATCH); + -- -20012 + WHEN ENV_MANAGER.ERR_UNKNOWN_PREFIX THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_UNKNOWN_PREFIX), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN_PREFIX, ENV_MANAGER.MSG_UNKNOWN_PREFIX); + -- -20013 + WHEN ENV_MANAGER.ERR_TABLE_NOT_EXISTS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_TABLE_NOT_EXISTS), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_TABLE_NOT_EXISTS, ENV_MANAGER.MSG_TABLE_NOT_EXISTS); + -- -20014 + WHEN ENV_MANAGER.ERR_COLUMN_NOT_EXISTS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_COLUMN_NOT_EXISTS), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_COLUMN_NOT_EXISTS, ENV_MANAGER.MSG_COLUMN_NOT_EXISTS); + -- -20015 + WHEN ENV_MANAGER.ERR_UNSUPPORTED_DATA_TYPE THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_UNSUPPORTED_DATA_TYPE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNSUPPORTED_DATA_TYPE, ENV_MANAGER.MSG_UNSUPPORTED_DATA_TYPE); + -- -20016 + WHEN ENV_MANAGER.ERR_MISSING_SOURCE_KEY THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_MISSING_SOURCE_KEY), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MISSING_SOURCE_KEY, ENV_MANAGER.MSG_MISSING_SOURCE_KEY); + -- -20017 + WHEN ENV_MANAGER.ERR_NULL_SOURCE_FILE_CONFIG_KEY THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_NULL_SOURCE_FILE_CONFIG_KEY), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_NULL_SOURCE_FILE_CONFIG_KEY, ENV_MANAGER.MSG_NULL_SOURCE_FILE_CONFIG_KEY); + -- -20018 + WHEN ENV_MANAGER.ERR_DUPLICATED_SOURCE_KEY THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_DUPLICATED_SOURCE_KEY), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_DUPLICATED_SOURCE_KEY, ENV_MANAGER.MSG_DUPLICATED_SOURCE_KEY); + -- -20019 + WHEN ENV_MANAGER.ERR_MISSING_CONTAINER_CONFIG THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_MISSING_CONTAINER_CONFIG), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MISSING_CONTAINER_CONFIG, ENV_MANAGER.MSG_MISSING_CONTAINER_CONFIG); + -- -20020 + WHEN ENV_MANAGER.ERR_MULTIPLE_CONTAINER_ENTRIES THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_MULTIPLE_CONTAINER_ENTRIES), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MULTIPLE_CONTAINER_ENTRIES, ENV_MANAGER.MSG_MULTIPLE_CONTAINER_ENTRIES); + -- -20021 + WHEN ENV_MANAGER.ERR_WRONG_DESTINATION_PARAM THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_WRONG_DESTINATION_PARAM), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_WRONG_DESTINATION_PARAM, ENV_MANAGER.MSG_WRONG_DESTINATION_PARAM); + -- -20022 + WHEN ENV_MANAGER.ERR_FILE_NOT_EXISTS_ON_CLOUD THEN + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_FILE_NOT_EXISTS_ON_CLOUD, vParameters, 'FILE_MANAGER'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_NOT_EXISTS_ON_CLOUD, ENV_MANAGER.MSG_FILE_NOT_EXISTS_ON_CLOUD); + -- -20023 + WHEN ENV_MANAGER.ERR_FILE_ALREADY_REGISTERED THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_FILE_ALREADY_REGISTERED), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_FILE_ALREADY_REGISTERED, ENV_MANAGER.MSG_FILE_ALREADY_REGISTERED); + -- -20024 + WHEN ENV_MANAGER.ERR_WRONG_DATE_TIMESTAMP_FORMAT THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_WRONG_DATE_TIMESTAMP_FORMAT), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_WRONG_DATE_TIMESTAMP_FORMAT, ENV_MANAGER.MSG_WRONG_DATE_TIMESTAMP_FORMAT); + + -- -20011 + WHEN ENV_MANAGER.ERR_EXCESS_COLUMNS_DETECTED THEN + ENV_MANAGER.LOG_PROCESS_ERROR(ENV_MANAGER.MSG_EXCESS_COLUMNS_DETECTED, vParameters, 'FILE_MANAGER'); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_EXCESS_COLUMNS_DETECTED, ENV_MANAGER.MSG_EXCESS_COLUMNS_DETECTED); + + -- -20999 + WHEN ENV_MANAGER.ERR_UNKNOWN THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> ENV_MANAGER.CODE_UNKNOWN), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + + + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN, 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + + END PROCESS_SOURCE_FILE; + + +---------------------------------------------------------------------------------------------------- + + FUNCTION PROCESS_SOURCE_FILE(pSourceFileReceivedName IN VARCHAR2) + RETURN PLS_INTEGER + IS + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileReceivedName => '||nvl(pSourceFileReceivedName, 'NULL'))); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + ---- + PROCESS_SOURCE_FILE(pSourceFileReceivedName => pSourceFileReceivedName); + ---- + 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 PROCESS_SOURCE_FILE; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_DATE_FORMAT( + pTemplateTableName IN VARCHAR2, + pColumnName IN VARCHAR2 + ) + RETURN VARCHAR2 + IS + vDateFormat A_COLUMN_DATE_FORMAT.DATE_FORMAT%TYPE; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vColumnName VARCHAR2(200); + vGetDefault BOOLEAN := FALSE; + BEGIN + vColumnName := trim(pColumnName); + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||'''' + ,'pColumnName => '''||nvl(vColumnName, 'NULL')||'''')); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + BEGIN + SELECT DATE_FORMAT + INTO vDateFormat + FROM CT_MRDS.A_COLUMN_DATE_FORMAT F + WHERE F.TEMPLATE_TABLE_NAME = pTemplateTableName + AND F.COLUMN_NAME = vColumnName; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + vGetDefault := TRUE; + WHEN TOO_MANY_ROWS THEN + -- Below error should not happened because: + -- Unique constraint added on table A_COLUMN_DATE_FORMAT on columns: (TEMPLATE_TABLE_NAME, COLUMN_NAME) + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MULTIPLE_COLUMN_DATE_FORMAT, ENV_MANAGER.MSG_MULTIPLE_COLUMN_DATE_FORMAT); + END; + IF vGetDefault THEN + BEGIN + SELECT DATE_FORMAT + INTO vDateFormat + FROM CT_MRDS.A_COLUMN_DATE_FORMAT F + WHERE F.TEMPLATE_TABLE_NAME = pTemplateTableName + AND F.COLUMN_NAME = 'DEFAULT'; + EXCEPTION + WHEN NO_DATA_FOUND THEN + vDateFormat := ENV_MANAGER.gvDefaultDateFormat; + END; + END IF; + + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters); + RETURN vDateFormat; + END GET_DATE_FORMAT; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE GENERATE_EXTERNAL_TABLE_PARAMS ( + + pTemplateTableName IN VARCHAR2, + pColumnList OUT CLOB, + pFieldList OUT CLOB + ) + IS + vSchemaName VARCHAR2(200); + vTableName VARCHAR2(200); + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vMaxColumnNameLength PLS_INTEGER := 0; + vColType varchar2(200); + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||'''' + ,'pColumnList => '''||nvl(pColumnList, 'NULL')||'''' + ,'pFieldList = '''||nvl(pFieldList, 'NULL')||'''' + )); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + vSchemaName := REPLACE(REGEXP_SUBSTR(pTemplateTableName,'.*\.'),'.',''); + ENV_MANAGER.LOG_PROCESS_EVENT('vSchemaName','DEBUG', vSchemaName); + vTableName := REPLACE(REGEXP_SUBSTR(pTemplateTableName,'\..*'),'.',''); + ENV_MANAGER.LOG_PROCESS_EVENT('vTableName','DEBUG', vTableName); + FOR rec IN ( + SELECT + '"'||column_name||'"' as quoted_column_name, + column_name, + data_type, + data_length, + char_length, -- MARS-1056: Added for CHAR/BYTE semantics + char_used, -- MARS-1056: Added for CHAR/BYTE semantics + data_precision, + data_scale, + column_id, + max(length(column_name)+1) over (partition by table_name) as max_column_name_length + FROM all_tab_columns + WHERE table_name = UPPER(vTableName) + AND owner = NVL(UPPER(vSchemaName), USER) + ORDER BY column_id + ) LOOP + -- Build the column_list string + rec.quoted_column_name := rpad(rec.quoted_column_name, rec.max_column_name_length+2, ' '); + + vColType := + CASE + -- MARS-1056: Fixed VARCHAR2 definition logic to preserve CHAR/BYTE semantics + WHEN rec.data_type = 'VARCHAR2' THEN + CASE + WHEN rec.char_used = 'C' THEN + rec.quoted_column_name || ' VARCHAR2(' || rec.char_length || ' CHAR)' + WHEN rec.char_used = 'B' THEN + rec.quoted_column_name || ' VARCHAR2(' || rec.data_length || ' BYTE)' + ELSE + -- Fallback for NULL char_used (should not occur but handle gracefully) + rec.quoted_column_name || ' VARCHAR2(' || rec.data_length || ')' + END + -- Other character types (preserve original logic) + WHEN rec.data_type IN ('CHAR', 'NCHAR', 'NVARCHAR2') THEN + rec.quoted_column_name || ' ' || rec.data_type || '(' || rec.data_length || ')' + WHEN rec.data_type = 'NUMBER' THEN + rec.quoted_column_name || ' ' || rec.data_type || + CASE + WHEN rec.data_precision IS NOT NULL AND rec.data_scale IS NOT NULL THEN + '(' || rec.data_precision || ',' || rec.data_scale || ')' + WHEN rec.data_precision IS NOT NULL THEN + '(' || rec.data_precision || ')' + ELSE + '' + END + WHEN rec.data_type IN ('RAW') THEN + rec.quoted_column_name || ' ' || rec.data_type || '(' || rec.data_length || ')' + WHEN REGEXP_SUBSTR(rec.data_type, '^[A-Z]+') IN ('DATE', 'TIMESTAMP') THEN + rec.quoted_column_name || ' ' || rec.data_type + ELSE + rec.quoted_column_name || ' ' || rec.data_type + END; + pColumnList := pColumnList ||vColType ||cgBL|| ','; + -- Build the field_list string + -- Note: field_list uses CHAR() for CSV field definitions - this is correct behavior + pFieldList := pFieldList || + CASE + WHEN rec.data_type = 'DATE' THEN + -- 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) + -- SQL*Loader syntax: CHAR(length) DATE_FORMAT TIMESTAMP MASK "format" (not: TIMESTAMP 'format') + rec.quoted_column_name || ' CHAR(35) DATE_FORMAT TIMESTAMP MASK ' || 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 + -- For CSV field definitions, use data_length for CHAR() specification + rec.quoted_column_name || ' CHAR(' || rec.data_length || ')' + ELSE + rec.quoted_column_name + END ||cgBL|| ','; + + + END LOOP; + + -- Remove the trailing comma and space from the strings + pColumnList := ' '||RTRIM(pColumnList, ','); + pFieldList := ' '||RTRIM(pFieldList, ','); + ENV_MANAGER.LOG_PROCESS_EVENT('vColumnList', 'DEBUG', pColumnList); + -- TO_DO !!! + -- Add check if pColumnList/pFieldList is empty or not + -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + + + -- Output the generated column_list and field_list + ENV_MANAGER.LOG_PROCESS_EVENT('column_list' ,'DEBUG',pColumnList); + ENV_MANAGER.LOG_PROCESS_EVENT('field_list' ,'DEBUG',pFieldList); + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters); + + EXCEPTION +-- WHEN ENV_MANAGER.ERR_MISSING_COLUMN_DATE_FORMAT THEN +-- ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_MISSING_COLUMN_DATE_FORMAT, 'ERROR', vParameters); +-- RAISE_ERROR(ENV_MANAGER.CODE_MISSING_COLUMN_DATE_FORMAT); + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + END GENERATE_EXTERNAL_TABLE_PARAMS; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE ADD_SOURCE ( + pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE, + pSourceName IN CT_MRDS.A_SOURCE.SOURCE_NAME%TYPE + ) IS + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + INSERT INTO CT_MRDS.A_SOURCE(A_SOURCE_KEY, SOURCE_NAME) VALUES (pSourceKey, pSourceName); + COMMIT; + EXCEPTION + WHEN DUP_VAL_ON_INDEX THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_DUPLICATED_SOURCE_KEY, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_DUPLICATED_SOURCE_KEY, ENV_MANAGER.MSG_DUPLICATED_SOURCE_KEY); + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + END ADD_SOURCE; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE DELETE_SOURCE_CASCADE ( + pSourceKey IN CT_MRDS.A_SOURCE.A_SOURCE_KEY%TYPE + ) IS + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + vSharedTemplateCount PLS_INTEGER := 0; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceKey => '''||nvl(pSourceKey, 'NULL')||'''')); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + + -- First pass: Delete container files (those that have CONTAINER_FILE_KEY set) + for rec in (select A_SOURCE_FILE_CONFIG_KEY, TEMPLATE_TABLE_NAME from CT_MRDS.A_SOURCE_FILE_CONFIG + where A_SOURCE_KEY = pSourceKey AND CONTAINER_FILE_KEY IS NOT NULL + ORDER BY A_SOURCE_FILE_CONFIG_KEY) loop + -- Delete processed file records + delete from CT_MRDS.A_SOURCE_FILE_RECEIVED WHERE A_SOURCE_FILE_CONFIG_KEY = rec.A_SOURCE_FILE_CONFIG_KEY; + ENV_MANAGER.LOG_PROCESS_EVENT('Deleted A_SOURCE_FILE_RECEIVED records for container config key: '||rec.A_SOURCE_FILE_CONFIG_KEY,'DEBUG', vParameters); + + -- Check if TEMPLATE_TABLE_NAME is shared with other source systems before deleting date formats + IF rec.TEMPLATE_TABLE_NAME IS NOT NULL THEN + SELECT COUNT(DISTINCT A_SOURCE_KEY) + INTO vSharedTemplateCount + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE TEMPLATE_TABLE_NAME = rec.TEMPLATE_TABLE_NAME + AND A_SOURCE_KEY <> pSourceKey; -- Exclude current source being deleted + + -- Only delete date formats if template table is not shared with other sources + IF vSharedTemplateCount = 0 THEN + delete from CT_MRDS.A_COLUMN_DATE_FORMAT WHERE TEMPLATE_TABLE_NAME = rec.TEMPLATE_TABLE_NAME; + ENV_MANAGER.LOG_PROCESS_EVENT('Deleted A_COLUMN_DATE_FORMAT records for template: '||rec.TEMPLATE_TABLE_NAME,'DEBUG', vParameters); + ELSE + ENV_MANAGER.LOG_PROCESS_EVENT('Skipping A_COLUMN_DATE_FORMAT deletion - template table '||rec.TEMPLATE_TABLE_NAME||' is shared with '||vSharedTemplateCount||' other source systems','WARNING', vParameters); + END IF; + END IF; + + -- Delete container file configuration + delete from CT_MRDS.A_SOURCE_FILE_CONFIG WHERE A_SOURCE_FILE_CONFIG_KEY = rec.A_SOURCE_FILE_CONFIG_KEY; + ENV_MANAGER.LOG_PROCESS_EVENT('Deleted container A_SOURCE_FILE_CONFIG record for config key: '||rec.A_SOURCE_FILE_CONFIG_KEY,'DEBUG', vParameters); + end loop; + COMMIT; -- Commit container deletions + + -- Second pass: Delete parent files (those that do NOT have CONTAINER_FILE_KEY set) + for rec in (select A_SOURCE_FILE_CONFIG_KEY, TEMPLATE_TABLE_NAME from CT_MRDS.A_SOURCE_FILE_CONFIG + where A_SOURCE_KEY = pSourceKey AND CONTAINER_FILE_KEY IS NULL + ORDER BY A_SOURCE_FILE_CONFIG_KEY) loop + -- Delete processed file records + delete from CT_MRDS.A_SOURCE_FILE_RECEIVED WHERE A_SOURCE_FILE_CONFIG_KEY = rec.A_SOURCE_FILE_CONFIG_KEY; + ENV_MANAGER.LOG_PROCESS_EVENT('Deleted A_SOURCE_FILE_RECEIVED records for parent config key: '||rec.A_SOURCE_FILE_CONFIG_KEY,'DEBUG', vParameters); + + -- Check if TEMPLATE_TABLE_NAME is shared with other source systems before deleting date formats + IF rec.TEMPLATE_TABLE_NAME IS NOT NULL THEN + SELECT COUNT(DISTINCT A_SOURCE_KEY) + INTO vSharedTemplateCount + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE TEMPLATE_TABLE_NAME = rec.TEMPLATE_TABLE_NAME + AND A_SOURCE_KEY <> pSourceKey; -- Exclude current source being deleted + + -- Only delete date formats if template table is not shared with other sources + IF vSharedTemplateCount = 0 THEN + delete from CT_MRDS.A_COLUMN_DATE_FORMAT WHERE TEMPLATE_TABLE_NAME = rec.TEMPLATE_TABLE_NAME; + ENV_MANAGER.LOG_PROCESS_EVENT('Deleted A_COLUMN_DATE_FORMAT records for template: '||rec.TEMPLATE_TABLE_NAME,'DEBUG', vParameters); + ELSE + ENV_MANAGER.LOG_PROCESS_EVENT('Skipping A_COLUMN_DATE_FORMAT deletion - template table '||rec.TEMPLATE_TABLE_NAME||' is shared with '||vSharedTemplateCount||' other source systems','WARNING', vParameters); + END IF; + END IF; + + -- Delete parent file configuration + delete from CT_MRDS.A_SOURCE_FILE_CONFIG WHERE A_SOURCE_FILE_CONFIG_KEY = rec.A_SOURCE_FILE_CONFIG_KEY; + ENV_MANAGER.LOG_PROCESS_EVENT('Deleted parent A_SOURCE_FILE_CONFIG record for config key: '||rec.A_SOURCE_FILE_CONFIG_KEY,'DEBUG', vParameters); + end loop; + COMMIT; -- Commit parent deletions + + -- Delete source system record + DELETE FROM CT_MRDS.A_SOURCE where A_SOURCE_KEY = pSourceKey; + ENV_MANAGER.LOG_PROCESS_EVENT('Deleted A_SOURCE record for source key: '||pSourceKey,'DEBUG', vParameters); + COMMIT; -- Final commit for source deletion + + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO', vParameters); + + EXCEPTION + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN, 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + END DELETE_SOURCE_CASCADE; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_CONTAINER_SOURCE_FILE_CONFIG_KEY ( + pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE + ) RETURN PLS_INTEGER + IS + vSourceFileConfigKey PLS_INTEGER; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileId => '||nvl(to_char(pSourceFileId), 'NULL'))); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + SELECT A_SOURCE_FILE_CONFIG_KEY + INTO vSourceFileConfigKey + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE SOURCE_FILE_ID = pSourceFileId + AND SOURCE_FILE_TYPE = 'CONTAINER'; + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters); + RETURN vSourceFileConfigKey; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + ENV_MANAGER.MSG_MISSING_CONTAINER_CONFIG := 'No match in A_SOURCE_FILE_CONFIG where SOURCE_FILE_TYPE=''CONTAINER'' and SOURCE_FILE_ID = '''||pSourceFileId||''''; + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_MISSING_CONTAINER_CONFIG, 'WARNING', vParameters); + RETURN NULL; + WHEN TOO_MANY_ROWS THEN + ENV_MANAGER.MSG_MULTIPLE_CONTAINER_ENTRIES := 'GET_CONTAINER_SOURCE_FILE_CONFIG_KEY: Multiple SOURCE_FILE_TYPE=''CONTAINER'' matches for SOURCE_FILE_ID: '||pSourceFileId||' in A_SOURCE_FILE_CONFIG'; + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_MULTIPLE_CONTAINER_ENTRIES, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MULTIPLE_CONTAINER_ENTRIES, ENV_MANAGER.MSG_MULTIPLE_CONTAINER_ENTRIES); + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + + END GET_CONTAINER_SOURCE_FILE_CONFIG_KEY; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_SOURCE_FILE_CONFIG_KEY ( + pSourceFileType IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE%TYPE DEFAULT 'INPUT' + ,pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE + ,pTableId IN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID%TYPE + ) RETURN PLS_INTEGER + IS + vSourceFileConfigKey PLS_INTEGER; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('pSourceFileType => '''||nvl(pSourceFileType, 'NULL')||'''' + ,'pSourceFileId => '''||nvl(pSourceFileId, 'NULL')||'''' + ,'pTableId => '''||nvl(pTableId, 'NULL')||'''')); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + SELECT A_SOURCE_FILE_CONFIG_KEY + INTO vSourceFileConfigKey + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE SOURCE_FILE_TYPE = pSourceFileType + AND SOURCE_FILE_ID = pSourceFileId + AND TABLE_ID = pTableId; + + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG', vParameters); + RETURN vSourceFileConfigKey; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + RETURN NULL; + WHEN TOO_MANY_ROWS THEN + vgMsgTmp := ENV_MANAGER.MSG_MULTIPLE_MATCH_FOR_SRCFILE + ||cgBL||' '||'GET_SOURCE_FILE_CONFIG_KEY: Multiple matches in A_SOURCE_FILE_CONFIG table WHERE' + ||cgBL||' '||'SOURCE_FILE_TYPE: '||pSourceFileType + ||cgBL||' '||'SOURCE_FILE_ID: '||pSourceFileId + ||cgBL||' '||'TABLE_ID: '||pTableId; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MULTIPLE_MATCH_FOR_SRCFILE, vgMsgTmp); + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.MSG_UNKNOWN); + + END GET_SOURCE_FILE_CONFIG_KEY; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE ADD_SOURCE_FILE_CONFIG ( + pSourceKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_KEY%TYPE + ,pSourceFileType IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_TYPE%TYPE + ,pSourceFileId IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_ID%TYPE + ,pSourceFileDesc IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_DESC%TYPE + ,pSourceFileNamePattern IN CT_MRDS.A_SOURCE_FILE_CONFIG.SOURCE_FILE_NAME_PATTERN%TYPE + ,pTableId IN CT_MRDS.A_SOURCE_FILE_CONFIG.TABLE_ID%TYPE DEFAULT NULL + ,pTemplateTableName IN CT_MRDS.A_SOURCE_FILE_CONFIG.TEMPLATE_TABLE_NAME%TYPE DEFAULT NULL + ,pContainerFileKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.CONTAINER_FILE_KEY%TYPE DEFAULT NULL + ,pEncoding IN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING%TYPE DEFAULT NULL -- MARS-1049: NOWY PARAMETR + ) IS + vSourceFileConfigKey PLS_INTEGER; + vSourceKeyExists PLS_INTEGER := 0; + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( 'pSourceKey => '''||nvl(to_char(pSourceKey), 'NULL')||'''' + ,'pSourceFileType => '''||nvl(to_char(pSourceFileType), 'NULL')||'''' + ,'pSourceFileId => '''||nvl(to_char(pSourceFileId), 'NULL')||'''' + ,'pSourceFileDesc => '''||nvl(to_char(pSourceFileDesc), 'NULL')||'''' + ,'pSourceFileNamePattern => '''||nvl(to_char(pSourceFileNamePattern), 'NULL')||'''' + ,'pTableId => '''||nvl(to_char(pTableId), 'NULL')||'''' + ,'pTemplateTableName => '''||nvl(to_char(pTemplateTableName), 'NULL')||'''' + ,'pContainerFileKey => '''||nvl(to_char(pContainerFileKey), 'NULL')||'''' + ,'pEncoding => '''||nvl(to_char(pEncoding), 'NULL')||'''' -- MARS-1049: NOWY + )); + ENV_MANAGER.LOG_PROCESS_EVENT('Start','INFO', vParameters); + INSERT INTO CT_MRDS.A_SOURCE_FILE_CONFIG(A_SOURCE_KEY, SOURCE_FILE_TYPE, SOURCE_FILE_ID, SOURCE_FILE_DESC, SOURCE_FILE_NAME_PATTERN, TABLE_ID, TEMPLATE_TABLE_NAME, CONTAINER_FILE_KEY, ENCODING) + VALUES (pSourceKey, pSourceFileType, pSourceFileId, pSourceFileDesc, pSourceFileNamePattern, pTableId, pTemplateTableName, pContainerFileKey, pEncoding); + COMMIT; + ENV_MANAGER.LOG_PROCESS_EVENT('End','INFO',vParameters); + EXCEPTION + + WHEN OTHERS THEN + IF SQLCODE = -2291 THEN + ENV_MANAGER.MSG_MISSING_SOURCE_KEY := 'The Source with A_SOURCE_KEY: '''||pSourceKey||''' not found in parent table A_SOURCE.' + ||cgBL||'First add a record to A_SOURCE:' + ||cgBL||'call file_manager.add_source(pSourceKey => '''||pSourceKey||''', pSourceName => ''...'')'; + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_MISSING_SOURCE_KEY, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_MISSING_SOURCE_KEY, ENV_MANAGER.MSG_MISSING_SOURCE_KEY); + ELSE + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN , 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + END IF; + + END ADD_SOURCE_FILE_CONFIG; + + ---------------------------------------------------------------------------------------------------- + + PROCEDURE ADD_COLUMN_DATE_FORMAT ( + pTemplateTableName IN CT_MRDS.A_COLUMN_DATE_FORMAT.TEMPLATE_TABLE_NAME%TYPE + ,pColumnName IN CT_MRDS.A_COLUMN_DATE_FORMAT.COLUMN_NAME%TYPE + ,pDateFormat IN CT_MRDS.A_COLUMN_DATE_FORMAT.DATE_FORMAT%TYPE + ) IS + vParameters CT_MRDS.A_PROCESS_LOG.PROCEDURE_PARAMETERS%TYPE; + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( 'pTemplateTableName => '''||nvl(pTemplateTableName, 'NULL')||'''' + ,'pColumnName => '''||nvl(pColumnName, 'NULL')||'''' + ,'pDateFormat => '''||nvl(pDateFormat, 'NULL')||'''' + )); + + ENV_MANAGER.LOG_PROCESS_EVENT('Start','DEBUG', vParameters); + INSERT INTO CT_MRDS.A_COLUMN_DATE_FORMAT(TEMPLATE_TABLE_NAME, COLUMN_NAME, DATE_FORMAT) + VALUES (pTemplateTableName, pColumnName, pDateFormat); + COMMIT; + + ENV_MANAGER.LOG_PROCESS_EVENT('End','DEBUG',vParameters); + EXCEPTION + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.MSG_UNKNOWN, 'ERROR', vParameters); + ENV_MANAGER.LOG_PROCESS_EVENT(ENV_MANAGER.GET_ERROR_STACK(pFormat => 'TABLE', pCode=> SQLCODE), 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + END ADD_COLUMN_DATE_FORMAT; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_BUCKET_URI(pBucketArea VARCHAR2) + RETURN VARCHAR2 + IS + BEGIN + CASE pBucketArea + WHEN 'INBOX' THEN RETURN ENV_MANAGER.gvInboxBucketUri; + WHEN 'ODS' THEN RETURN ENV_MANAGER.gvDataBucketUri; + WHEN 'DATA' THEN RETURN ENV_MANAGER.gvDataBucketUri; + WHEN 'ARCHIVE' THEN RETURN ENV_MANAGER.gvArchiveBucketUri; + ELSE + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_INVALID_BUCKET_AREA, + ENV_MANAGER.MSG_INVALID_BUCKET_AREA || ' Provided: ''' || pBucketArea || ''''); + END CASE; + END; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_DET_SOURCE_FILE_CONFIG_INFO ( + pSourceFileConfigKey IN CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE + ,pIncludeContainerInfo IN PLS_INTEGER DEFAULT 1 + ,pIncludeColumnFormatInfo IN PLS_INTEGER DEFAULT 1 + ) RETURN VARCHAR2 + ---- + -- Function to get info about File Configuration entry + IS + vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE; + vContainerFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE; + vCount PLS_INTEGER := 0; + addColHeader BOOLEAN := TRUE; + vMsgTmp VARCHAR2(32000):= ''; + CURSOR cColumnFormat(vTableName A_COLUMN_DATE_FORMAT.TEMPLATE_TABLE_NAME%TYPE) IS + SELECT * + FROM CT_MRDS.A_COLUMN_DATE_FORMAT + WHERE TEMPLATE_TABLE_NAME = vTableName; + vColumnDateFormat A_COLUMN_DATE_FORMAT%ROWTYPE; + + FUNCTION FORMAT_CONFIG( pSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE, + pTypeInfo VARCHAR2 DEFAULT 'File Configuration', + pLevel VARCHAR2 DEFAULT '') + RETURN VARCHAR2 + IS + vMsg VARCHAR2(9999); + BEGIN + vMsg := '' + ||cgBL||pLevel||''||'Details about '||pTypeInfo||':' + ||cgBL||pLevel||''||'--------------------------------' + ||cgBL||pLevel||'A_SOURCE_FILE_CONFIG_KEY = '||pSourceFileConfig.A_SOURCE_FILE_CONFIG_KEY + ||cgBL||pLevel||'A_SOURCE_KEY = '||pSourceFileConfig.A_SOURCE_KEY + ||cgBL||pLevel||'SOURCE_FILE_TYPE = '||pSourceFileConfig.SOURCE_FILE_TYPE + ||cgBL||pLevel||'SOURCE_FILE_ID = '||pSourceFileConfig.SOURCE_FILE_ID + ||cgBL||pLevel||'SOURCE_FILE_DESC = '||pSourceFileConfig.SOURCE_FILE_DESC + ||cgBL||pLevel||'SOURCE_FILE_NAME_PATTERN = '||pSourceFileConfig.SOURCE_FILE_NAME_PATTERN + ||cgBL||pLevel||'TABLE_ID = '||pSourceFileConfig.TABLE_ID + ||cgBL||pLevel||'TEMPLATE_TABLE_NAME = '||pSourceFileConfig.TEMPLATE_TABLE_NAME + ||cgBL||pLevel||'CONTAINER_FILE_KEY = '||pSourceFileConfig.CONTAINER_FILE_KEY + ||cgBL||pLevel||'ODS_SCHEMA_NAME = '||pSourceFileConfig.ODS_SCHEMA_NAME + ||cgBL||pLevel||'ARCHIVE_THRESHOLD_DAYS = '||pSourceFileConfig.ARCHIVE_THRESHOLD_DAYS + ||cgBL||pLevel||'ARCHIVE_THRESHOLD_FILES_COUNT = '||pSourceFileConfig.ARCHIVE_THRESHOLD_FILES_COUNT + ||cgBL||pLevel||'ARCHIVE_THRESHOLD_BYTES_SUM = '||pSourceFileConfig.ARCHIVE_THRESHOLD_BYTES_SUM + ||cgBL||pLevel||'ARCHIVE_THRESHOLD_ROWS_COUNT = '||pSourceFileConfig.ARCHIVE_THRESHOLD_ROWS_COUNT + ||cgBL||pLevel||'HOURS_TO_EXPIRE_STATISTICS = '||pSourceFileConfig.HOURS_TO_EXPIRE_STATISTICS + + ||cgBL||pLevel||''||'--------------------------------' + ; + RETURN vMsg; + END FORMAT_CONFIG; + + BEGIN + vMsgTmp := ''; + -- Get Main Config + BEGIN + SELECT * + INTO vSourceFileConfig + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey; + + vMsgTmp := FORMAT_CONFIG(pSourceFileConfig => vSourceFileConfig, pTypeInfo => 'File Configuration'); + EXCEPTION + WHEN NO_DATA_FOUND THEN + vMsgTmp := 'There is no config entry in A_SOURCE_FILE_CONFIG where A_SOURCE_FILE_CONFIG_KEY = '||pSourceFileConfigKey; + RETURN vMsgTmp; + END; + + -- Get Container Config + IF pIncludeContainerInfo > 0 THEN + BEGIN + SELECT * + INTO vContainerFileConfig + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE A_SOURCE_FILE_CONFIG_KEY = vSourceFileConfig.CONTAINER_FILE_KEY; + + vMsgTmp := vMsgTmp || cgBL || FORMAT_CONFIG(pSourceFileConfig => vContainerFileConfig, pTypeInfo => 'related Container Config', pLevel => ' '); + + EXCEPTION + WHEN NO_DATA_FOUND THEN + vMsgTmp := vMsgTmp|| cgBL || 'There is no CONTAINER config entry in A_SOURCE_FILE_CONFIG.'; + -- RETURN vMsgTmp; + END; + END IF; + + -- Get Column Date Format Config + IF pIncludeColumnFormatInfo > 0 THEN + BEGIN + OPEN cColumnFormat(vTableName => vSourceFileConfig.TEMPLATE_TABLE_NAME); + LOOP + FETCH cColumnFormat INTO vColumnDateFormat; + IF cColumnFormat%FOUND AND addColHeader THEN + vCount := 1; + vMsgTmp := vMsgTmp||cgBL|| cgBL || ' Column Date Format config entries:'; + vMsgTmp := vMsgTmp||cgBL||''||' --------------------------------'; + addColHeader := FALSE; + END IF; + EXIT WHEN cColumnFormat%NOTFOUND; + vMsgTmp := vMsgTmp + ||cgBL||' TEMPLATE_TABLE_NAME = '||vColumnDateFormat.TEMPLATE_TABLE_NAME + ||cgBL||' COLUMN_NAME = '||vColumnDateFormat.COLUMN_NAME + ||cgBL||' DATE_FORMAT = '||vColumnDateFormat.DATE_FORMAT + ||cgBL||''||' --------------------------------'; + END LOOP; + If vCount=0 THEN + vMsgTmp := vMsgTmp || cgBL || 'There is no Column Date Format config entries in A_COLUMN_DATE_FORMAT where TEMPLATE_TABLE_NAME = '||NVL(vSourceFileConfig.TEMPLATE_TABLE_NAME,'NULL'); + END IF; + CLOSE cColumnFormat; + END; + END IF; + + RETURN vMsgTmp; + EXCEPTION + + WHEN OTHERS THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + + END GET_DET_SOURCE_FILE_CONFIG_INFO; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_DET_SOURCE_FILE_RECEIVED_INFO ( + pSourceFileReceivedKey IN CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE + ,pIncludeConfigInfo IN PLS_INTEGER DEFAULT 1 + ,pIncludeContainerInfo IN PLS_INTEGER DEFAULT 1 + ,pIncludeColumnFormatInfo IN PLS_INTEGER DEFAULT 1 + ) RETURN VARCHAR2 + ---- + -- Function to get info about File Received entry + IS + vSourceFileReceived CT_MRDS.A_SOURCE_FILE_RECEIVED%ROWTYPE; + vMsgTmp VARCHAR2(32000):= ''; + BEGIN + + BEGIN + SELECT * + INTO vSourceFileReceived + FROM CT_MRDS.A_SOURCE_FILE_RECEIVED + WHERE A_SOURCE_FILE_RECEIVED_KEY = pSourceFileReceivedKey; + + vMsgTmp := '' + ||cgBL||''||'Details about received file:' + ||cgBL||''||'--------------------------------' + ||cgBL||'A_SOURCE_FILE_RECEIVED_KEY = '||vSourceFileReceived.A_SOURCE_FILE_RECEIVED_KEY + ||cgBL||'A_SOURCE_FILE_CONFIG_KEY = '||vSourceFileReceived.A_SOURCE_FILE_CONFIG_KEY + ||cgBL||'SOURCE_FILE_NAME = '||vSourceFileReceived.SOURCE_FILE_NAME + ||cgBL||'CHECKSUM = '||vSourceFileReceived.CHECKSUM + ||cgBL||'CREATED = '||vSourceFileReceived.CREATED + ||cgBL||'BYTES = '||vSourceFileReceived.BYTES + ||cgBL||'RECEPTION_DATE = '||vSourceFileReceived.RECEPTION_DATE + ||cgBL||'PROCESSING_STATUS = '||vSourceFileReceived.PROCESSING_STATUS + ||cgBL||'EXTERNAL_TABLE_NAME = '||vSourceFileReceived.EXTERNAL_TABLE_NAME + ||cgBL||'PARTITION_YEAR = '||vSourceFileReceived.PARTITION_YEAR + ||cgBL||'PARTITION_MONTH = '||vSourceFileReceived.PARTITION_MONTH + ||cgBL||''||'--------------------------------' + ; + EXCEPTION + WHEN NO_DATA_FOUND THEN + vMsgTmp := 'There is no data in A_SOURCE_FILE_RECEIVED where A_SOURCE_FILE_RECEIVED_KEY = '||pSourceFileReceivedKey; + RETURN vMsgTmp; + END; + + IF pIncludeConfigInfo>0 THEN + vMsgTmp := vMsgTmp || cgBL || CT_MRDS.FILE_MANAGER.GET_DET_SOURCE_FILE_CONFIG_INFO(vSourceFileReceived.A_SOURCE_FILE_CONFIG_KEY,pIncludeContainerInfo,pIncludeColumnFormatInfo); + END IF; + RETURN vMsgTmp; + EXCEPTION + + WHEN OTHERS THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + + END GET_DET_SOURCE_FILE_RECEIVED_INFO; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_DET_USER_LOAD_OPERATIONS ( + pOperationId PLS_INTEGER + ) RETURN VARCHAR2 + ---- + -- Function to get info about File Received entry + IS + vUserLoadOperations USER_LOAD_OPERATIONS%ROWTYPE; + vMsgTmp VARCHAR2(32000):= ''; + BEGIN + + BEGIN + SELECT * + INTO vUserLoadOperations + FROM USER_LOAD_OPERATIONS + WHERE id = pOperationId; + + vMsgTmp := '' + ||''||'Details about USER_LOAD_OPERATIONS where ID = '||pOperationId + ||cgBL||''||'--------------------------------' + ||cgBL||'ID = '||vUserLoadOperations.ID + ||cgBL||'TYPE = '||vUserLoadOperations.TYPE + ||cgBL||'SID = '||vUserLoadOperations.SID + ||cgBL||'SERIAL# = '||vUserLoadOperations.SERIAL# + ||cgBL||'START_TIME = '||vUserLoadOperations.START_TIME + ||cgBL||'UPDATE_TIME = '||vUserLoadOperations.UPDATE_TIME + ||cgBL||'STATUS = '||vUserLoadOperations.STATUS + ||cgBL||'OWNER_NAME = '||vUserLoadOperations.OWNER_NAME + ||cgBL||'TABLE_NAME = '||vUserLoadOperations.TABLE_NAME + ||cgBL||'PARTITION_NAME = '||vUserLoadOperations.PARTITION_NAME + ||cgBL||'SUBPARTITION_NAME = '||vUserLoadOperations.SUBPARTITION_NAME + ||cgBL||'FILE_URI_LIST = '||vUserLoadOperations.FILE_URI_LIST + ||cgBL||'ROWS_LOADED = '||vUserLoadOperations.ROWS_LOADED + ||cgBL||'LOGFILE_TABLE = '||vUserLoadOperations.LOGFILE_TABLE + ||cgBL||'BADFILE_TABLE = '||vUserLoadOperations.BADFILE_TABLE + ||cgBL||'STATUS_TABLE = '||vUserLoadOperations.STATUS_TABLE + ||cgBL||'TEMPEXT_TABLE = '||vUserLoadOperations.TEMPEXT_TABLE + ||cgBL||'CREDENTIAL_NAME = '||vUserLoadOperations.CREDENTIAL_NAME + ||cgBL||'EXPIRATION_TIME = '||vUserLoadOperations.EXPIRATION_TIME + ||cgBL||''||'--------------------------------' + ; + EXCEPTION + WHEN NO_DATA_FOUND THEN + vMsgTmp := 'There is no data in USER_LOAD_OPERATIONS where ID = '||pOperationId; + RETURN vMsgTmp; + END; + + RETURN vMsgTmp; + EXCEPTION + + WHEN OTHERS THEN + RAISE_APPLICATION_ERROR(ENV_MANAGER.CODE_UNKNOWN, ENV_MANAGER.GET_ERROR_STACK(pFormat => 'OUTPUT', pCode=> SQLCODE)); + + END GET_DET_USER_LOAD_OPERATIONS; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION ANALYZE_VALIDATION_ERRORS( + pSourceFileReceivedKey IN NUMBER + ) RETURN VARCHAR2 + IS + vSourceFileReceived CT_MRDS.A_SOURCE_FILE_RECEIVED%ROWTYPE; + vSourceFileConfig CT_MRDS.A_SOURCE_FILE_CONFIG%ROWTYPE; + vValidationLogTable VARCHAR2(128); + vTemplateSchema VARCHAR2(128); + vTemplateTable VARCHAR2(128); + vCsvFileUri VARCHAR2(4000); + vParameters VARCHAR2(4000); + vResult VARCHAR2(32000); + BEGIN + vParameters := ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST( + 'pSourceFileReceivedKey => ' || pSourceFileReceivedKey + )); + ENV_MANAGER.LOG_PROCESS_EVENT('Start', 'DEBUG', vParameters); + + -- Get file and config information + BEGIN + -- Get source file received data first + SELECT * + INTO vSourceFileReceived + FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr + WHERE sfr.A_SOURCE_FILE_RECEIVED_KEY = pSourceFileReceivedKey; + + -- Get source file config data + SELECT * + INTO vSourceFileConfig + FROM CT_MRDS.A_SOURCE_FILE_CONFIG sfc + WHERE sfc.A_SOURCE_FILE_CONFIG_KEY = vSourceFileReceived.A_SOURCE_FILE_CONFIG_KEY; + EXCEPTION + WHEN NO_DATA_FOUND THEN + ENV_MANAGER.LOG_PROCESS_ERROR('Source file or config not found for key: ' || pSourceFileReceivedKey, vParameters); + RETURN 'Error: Source file with key ' || pSourceFileReceivedKey || ' not found in A_SOURCE_FILE_RECEIVED table'; + END; + + -- Extract template schema and table from template table name + vTemplateSchema := REGEXP_SUBSTR(vSourceFileConfig.TEMPLATE_TABLE_NAME, '^([^.]+)'); + vTemplateTable := REGEXP_SUBSTR(vSourceFileConfig.TEMPLATE_TABLE_NAME, '\.(.+)$', 1, 1, NULL, 1); + + -- Build CSV file URI + vCsvFileUri := ENV_MANAGER.gvInboxBucketUri || + 'INBOX/' || vSourceFileConfig.A_SOURCE_KEY || '/' || + vSourceFileConfig.SOURCE_FILE_ID || '/' || + vSourceFileConfig.TABLE_ID || '/' || + vSourceFileReceived.SOURCE_FILE_NAME; + + -- Find validation log table (most recent one with errors) + -- Look for validation log tables related to this external table + BEGIN + SELECT table_name + INTO vValidationLogTable + FROM ( + SELECT table_name, + REGEXP_SUBSTR(table_name, '\$([0-9]+)_', 1, 1, NULL, 1) as log_number + FROM USER_TABLES + WHERE table_name LIKE 'VALIDATE$%_LOG' + ORDER BY TO_NUMBER(log_number) DESC + ) + WHERE ROWNUM = 1; + EXCEPTION + WHEN NO_DATA_FOUND THEN + -- If no validation log tables found, use a default name + vValidationLogTable := 'VALIDATE$999_LOG'; + END; + + ENV_MANAGER.LOG_PROCESS_EVENT('Calling ENV_MANAGER.ANALYZE_VALIDATION_ERRORS with parameters: ' || + 'LogTable=' || vValidationLogTable || + ', Schema=' || vTemplateSchema || + ', Table=' || vTemplateTable || + ', URI=' || SUBSTR(vCsvFileUri, 1, 100) || '...', 'DEBUG', vParameters); + + -- Call the main function with derived parameters + vResult := ENV_MANAGER.ANALYZE_VALIDATION_ERRORS( + pValidationLogTable => vValidationLogTable, + pTemplateSchema => vTemplateSchema, + pTemplateTable => vTemplateTable, + pCsvFileUri => vCsvFileUri + ); + + ENV_MANAGER.LOG_PROCESS_EVENT('End', 'DEBUG', vParameters); + RETURN vResult; + + EXCEPTION + WHEN OTHERS THEN + ENV_MANAGER.LOG_PROCESS_ERROR('Error in ANALYZE_VALIDATION_ERRORS: ' || SQLERRM, vParameters); + RETURN 'Error analyzing validation errors: ' || SQLERRM || + cgBL || 'Source File Key: ' || pSourceFileReceivedKey || + cgBL || 'Check A_SOURCE_FILE_RECEIVED and A_SOURCE_FILE_CONFIG tables for data integrity.'; + END ANALYZE_VALIDATION_ERRORS; + + ---------------------------------------------------------------------------------------------------- + -- EXTERNAL TABLE BATCH OPERATIONS IMPLEMENTATION (MARS-1057) + ---------------------------------------------------------------------------------------------------- + + PROCEDURE CREATE_EXTERNAL_TABLES_SET ( + pSourceFileConfigKey IN NUMBER, + pRecreate IN BOOLEAN DEFAULT FALSE, + pRestoreGrants IN BOOLEAN DEFAULT TRUE, + pArea IN VARCHAR2 DEFAULT 'ALL' + ) + 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); + vSourceFileId VARCHAR2(100); + vTableId VARCHAR2(100); + vTemplateTableName VARCHAR2(200); + vEncoding VARCHAR2(50); + vDelimiter VARCHAR2(10); + + vInboxTableName VARCHAR2(200); + vOdsTableName VARCHAR2(200); + vArchiveTableName VARCHAR2(200); + + vInboxPrefix VARCHAR2(500); + vOdsPrefix VARCHAR2(500); + vArchivePrefix VARCHAR2(500); + + 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 + BEGIN + ENV_MANAGER.LOG_PROCESS_EVENT('Attempting to drop table: ' || pTableName, 'DEBUG'); + EXECUTE IMMEDIATE 'DROP TABLE ' || SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') || '.' || pTableName; + ENV_MANAGER.LOG_PROCESS_EVENT('Table dropped successfully: ' || pTableName, 'INFO'); + EXCEPTION + 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'); + RAISE; -- Re-raise if not "table not exists" error + END IF; + END DROP_IF_EXISTS; + + 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( + 'pSourceFileConfigKey => ' || NVL(TO_CHAR(pSourceFileConfigKey), 'NULL'), + '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); + + -- 1. Retrieve configuration from A_SOURCE_FILE_CONFIG + BEGIN + SELECT A_SOURCE_KEY, SOURCE_FILE_ID, TABLE_ID, TEMPLATE_TABLE_NAME, + NVL(ENCODING, 'UTF8') + INTO vSourceKey, vSourceFileId, vTableId, vTemplateTableName, + vEncoding + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE A_SOURCE_FILE_CONFIG_KEY = pSourceFileConfigKey; + + -- Set default delimiter (column DELIMITER does not exist in A_SOURCE_FILE_CONFIG) + vDelimiter := ','; + EXCEPTION + WHEN NO_DATA_FOUND THEN + vgMsgTmp := 'Source file config not found: ' || pSourceFileConfigKey; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(-20001, vgMsgTmp); + END; + + -- 2. Generate table names + vInboxTableName := vTableId || '_INBOX'; + vOdsTableName := vTableId || '_ODS'; + vArchiveTableName := vTableId || '_ARCHIVE'; + + -- 3. Generate paths (OFFICIAL PATH PATTERNS) + vInboxPrefix := 'INBOX/' || vSourceKey || '/' || vSourceFileId || '/' || vTableId; + vOdsPrefix := 'ODS/' || vSourceKey || '/' || vTableId; + vArchivePrefix := 'ARCHIVE/' || vSourceKey || '/' || vTableId; + + ENV_MANAGER.LOG_PROCESS_EVENT( + 'Creating external tables for: ' || vSourceKey || '/' || vSourceFileId || '/' || vTableId || + ' (Area: ' || vAreaUpper || ')', + 'INFO' + ); + + -- 4. DROP existing tables if pRecreate = TRUE + IF pRecreate THEN + -- Save grants before dropping tables (if pRestoreGrants = TRUE) + IF pRestoreGrants THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Saving grants before dropping tables...', 'INFO'); + + IF vAreaUpper IN ('INBOX', 'ALL') THEN + SAVE_GRANTS(vInboxTableName, vInboxGrants); + END IF; + + 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'); + CREATE_EXTERNAL_TABLE( + pTableName => vInboxTableName, + pTemplateTableName => vTemplateTableName, + pPrefix => vInboxPrefix, + pBucketUri => ENV_MANAGER.gvInboxBucketUri, + pDelimiter => vDelimiter, + pEncoding => vEncoding + ); + END IF; + + -- 6. Create ODS external table (if requested) + IF vAreaUpper IN ('ODS', 'ALL') THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Creating ODS external table: ' || vOdsTableName, 'INFO'); + CREATE_EXTERNAL_TABLE( + pTableName => vOdsTableName, + pTemplateTableName => vTemplateTableName, + pPrefix => vOdsPrefix, + pBucketUri => ENV_MANAGER.gvDataBucketUri, + pDelimiter => vDelimiter, + pEncoding => vEncoding + ); + END IF; + + -- 7. Create ARCHIVE external table (if requested) + IF vAreaUpper IN ('ARCHIVE', 'ALL') THEN + ENV_MANAGER.LOG_PROCESS_EVENT('Creating ARCHIVE external table: ' || vArchiveTableName, 'INFO'); + CREATE_EXTERNAL_TABLE( + pTableName => vArchiveTableName, + pTemplateTableName => vTemplateTableName, + pPrefix => vArchivePrefix, + pBucketUri => ENV_MANAGER.gvArchiveBucketUri, + pDelimiter => vDelimiter, + 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( + 'End CREATE_EXTERNAL_TABLES_SET - Successfully created external tables for config: ' || + pSourceFileConfigKey || ' (Area: ' || vAreaUpper || ')', + 'INFO', + vParameters + ); + + EXCEPTION + WHEN OTHERS THEN + vgMsgTmp := 'Error creating external tables for config ' || pSourceFileConfigKey || ': ' || SQLERRM; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', vParameters); + RAISE_APPLICATION_ERROR(-20002, vgMsgTmp); + END CREATE_EXTERNAL_TABLES_SET; + + ---------------------------------------------------------------------------------------------------- + + 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, + pRestoreGrants IN BOOLEAN DEFAULT TRUE, + pArea IN VARCHAR2 DEFAULT 'ALL' + ) + IS + vCount NUMBER := 0; + vProcessed NUMBER := 0; + vFailed NUMBER := 0; + vParameters VARCHAR2(4000); + vAreaUpper VARCHAR2(20); + 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( + 'pSourceKey => ''' || NVL(pSourceKey, 'NULL') || '''', + 'pSourceFileId => ''' || NVL(pSourceFileId, 'NULL') || '''', + 'pTableId => ''' || NVL(pTableId, 'NULL') || '''', + '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); + + -- Iterate over configurations matching criteria (only INPUT files) + FOR rec IN ( + SELECT A_SOURCE_FILE_CONFIG_KEY, A_SOURCE_KEY, SOURCE_FILE_ID, TABLE_ID + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE SOURCE_FILE_TYPE = 'INPUT' + AND (pSourceKey IS NULL OR A_SOURCE_KEY = pSourceKey) + AND (pSourceFileId IS NULL OR SOURCE_FILE_ID = pSourceFileId) + AND (pTableId IS NULL OR TABLE_ID = pTableId) + ORDER BY A_SOURCE_KEY, SOURCE_FILE_ID, TABLE_ID + ) LOOP + vCount := vCount + 1; + + BEGIN + ENV_MANAGER.LOG_PROCESS_EVENT( + 'Creating external tables set for: ' || rec.A_SOURCE_KEY || '/' || + rec.SOURCE_FILE_ID || '/' || rec.TABLE_ID || ' (Area: ' || vAreaUpper || ')', + 'INFO' + ); + + -- Call procedure to create set of tables (based on pArea) + CREATE_EXTERNAL_TABLES_SET( + pSourceFileConfigKey => rec.A_SOURCE_FILE_CONFIG_KEY, + pRecreate => pRecreate, + pRestoreGrants => pRestoreGrants, + pArea => vAreaUpper + ); + + vProcessed := vProcessed + 1; + + EXCEPTION + WHEN OTHERS THEN + vFailed := vFailed + 1; + ENV_MANAGER.LOG_PROCESS_EVENT( + 'Failed to create tables for config ' || rec.A_SOURCE_FILE_CONFIG_KEY || + ' (' || rec.A_SOURCE_KEY || '/' || rec.SOURCE_FILE_ID || '/' || rec.TABLE_ID || '): ' || SQLERRM, + 'ERROR' + ); + -- Continue processing despite error + END; + END LOOP; + + ENV_MANAGER.LOG_PROCESS_EVENT( + 'End CREATE_EXTERNAL_TABLES_BATCH - Total: ' || vCount || + ', Processed: ' || vProcessed || ', Failed: ' || vFailed || ' (Area: ' || vAreaUpper || ')', + 'INFO', + vParameters + ); + + IF vFailed > 0 THEN + vgMsgTmp := 'Batch completed with errors. Processed: ' || vProcessed || ', Failed: ' || vFailed; + ENV_MANAGER.LOG_PROCESS_EVENT(vgMsgTmp, 'WARNING', vParameters); + RAISE_APPLICATION_ERROR(-20003, vgMsgTmp); + END IF; + + END CREATE_EXTERNAL_TABLES_BATCH; + + ---------------------------------------------------------------------------------------------------- + -- 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 ENV_MANAGER.GET_PACKAGE_VERSION_INFO( + pPackageName => 'FILE_MANAGER', + pVersion => PACKAGE_VERSION, + pBuildDate => PACKAGE_BUILD_DATE, + pAuthor => PACKAGE_AUTHOR + ); + END GET_BUILD_INFO; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_VERSION_HISTORY + RETURN VARCHAR2 + IS + BEGIN + RETURN ENV_MANAGER.FORMAT_VERSION_HISTORY( + pPackageName => 'FILE_MANAGER', + pVersionHistory => VERSION_HISTORY + ); + END GET_VERSION_HISTORY; + + ---------------------------------------------------------------------------------------------------- + +END; + +/ + + GRANT EXECUTE ON "CT_MRDS"."FILE_MANAGER" TO "ODS"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/Generated-20260302130055.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/Generated-20260302130055.sql new file mode 100644 index 0000000..760a946 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/Generated-20260302130055.sql @@ -0,0 +1,114 @@ +-------------------------------------------------------- +-- File created - Monday-March-02-2026 +-------------------------------------------------------- +@C:\Users\michalz\Documents\sql\export\CT_MRDS\DRARIDMC.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\T_FILENAME.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\T_FILENAMES.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_CONFIG_KEY_SEQ.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_RECEIVED_KEY_SEQ.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TABLE_STAT_KEY_SEQ.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TASK_HISTORY_KEY_SEQ.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TASK_HISTORY_SOURCE_KEY_SEQ.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TASK_HISTORY_TARGET_KEY_SEQ.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_WORKFLOW_HISTORY_KEY_SEQ.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_CASPER_FILEVAULT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_COLUMN_DATE_FORMAT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_METADATA_INVENTORY.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_LOG.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_MOPDB.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_RAR.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_RQSD.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_SOURCES_IGAM.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_FILE_MANAGER_CONFIG.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_PACKAGE_VERSION_TRACKING.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_PARALLEL_EXPORT_CHUNKS.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_PROCESS_LOG.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_CONFIG.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_RECEIVED.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TABLE_STAT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TABLE_STAT_HIST.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TASK_HISTORY.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TASK_HISTORY_SOURCE.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TASK_HISTORY_TARGET.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_WORKFLOW_HISTORY.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_WORKFLOW_HISTORY_PROPERTY.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\ERR_LOG.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_MOPDB_LOAD_HISTORY.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_COLUMN_DATE_FORMAT_PK.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_CONFIG_PK.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_CONFIG_UQ1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_RECEIVED_PK.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_RECEIVED_UK1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_PK.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TABLE_STAT_UK1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_WORKFLOW_HISTORY_PROPERTY_IDX1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\PK_PARALLEL_EXPORT_CHUNKS.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C00142356.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C0062744.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C0062752.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C0062756.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C0062776.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_IL0000608162C00009__.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_IL0000609457C00004__.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_IL0001159131C00010__.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\UK_PKG_VERSION_TRACK.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_COLUMN_DATE_FORMAT_PK_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C0062744_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C00142356_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\UK_PKG_VERSION_TRACK_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\PK_PARALLEL_EXPORT_CHUNKS_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C0062776_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_PK_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_CONFIG_PK_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_CONFIG_UQ1_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_RECEIVED_PK_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_RECEIVED_UK1_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C0062752_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TABLE_STAT_UK1_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\SYS_C0062756_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_WORKFLOW_HISTORY_PROPERTY_IDX1_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_RAR_TRG.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_WORKFLOW_HISTORY_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\TRG_A_DEVO_REPLICA_MGMT_MOPDB.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\TRG_BIU_CHCK_TEMPLATE_TABLE_NAME.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\TRG_BI_A_SOURCE_FILE_CONFIG_CHECK.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\TRG_BI_A_SRC_FILE_CFG_ARCH_VAL.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\TRG_BIU_CHCK_TEMPLATE_TABLE_NAME_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\TRG_A_DEVO_REPLICA_MGMT_MOPDB_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_RAR_TRG_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\TRG_BI_A_SOURCE_FILE_CONFIG_CHECK_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\TRG_BI_A_SRC_FILE_CFG_ARCH_VAL_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_WORKFLOW_HISTORY_2.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\M_DWH_ADD_LOAD_INFO_START.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\DATA_EXPORTER.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\ENV_MANAGER.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\FILE_ARCHIVER.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\FILE_MANAGER.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\WORKFLOW_MANAGER.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\DATA_EXPORTER_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\ENV_MANAGER_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\FILE_ARCHIVER_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\FILE_MANAGER_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\WORKFLOW_MANAGER_1.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\CHECK_LINK.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\DBMS_REGISTRY_SYS.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\UTL_RECOMP.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\UTL_RECOMP_ERRORS.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_COLUMN_DATE_FORMAT_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_METADATA_INVENTORY_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_LOG_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_MOPDB_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_RAR_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_DEVO_REPLICA_MGMT_RQSD_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_FILE_MANAGER_CONFIG_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_PACKAGE_VERSION_TRACKING_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_PARALLEL_EXPORT_CHUNKS_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_PROCESS_LOG_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_CONFIG_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_RECEIVED_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TABLE_STAT_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_TABLE_STAT_HIST_CONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_CONFIG_REFCONSTRAINT.sql +@C:\Users\michalz\Documents\sql\export\CT_MRDS\A_SOURCE_FILE_RECEIVED_REFCONSTRAINT.sql diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/M_DWH_ADD_LOAD_INFO_START.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/M_DWH_ADD_LOAD_INFO_START.sql new file mode 100644 index 0000000..058ba38 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/M_DWH_ADD_LOAD_INFO_START.sql @@ -0,0 +1,11 @@ +-------------------------------------------------------- +-- DDL for Procedure M_DWH_ADD_LOAD_INFO_START +-------------------------------------------------------- +set define off; + + CREATE OR REPLACE EDITIONABLE PROCEDURE "PDBADMIN"."M_DWH_ADD_LOAD_INFO_START" (db_key OUT NUMBER) +AS BEGIN +SELECT CT_MOPDB.AK_A_LOAD_HISTORY_MARS.NEXTVAL INTO db_key FROM DUAL; +END; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/PK_PARALLEL_EXPORT_CHUNKS.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/PK_PARALLEL_EXPORT_CHUNKS.sql new file mode 100644 index 0000000..279ab20 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/PK_PARALLEL_EXPORT_CHUNKS.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index PK_PARALLEL_EXPORT_CHUNKS +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."PK_PARALLEL_EXPORT_CHUNKS" ON "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" ("TASK_NAME", "CHUNK_ID") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/PK_PARALLEL_EXPORT_CHUNKS_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/PK_PARALLEL_EXPORT_CHUNKS_1.sql new file mode 100644 index 0000000..279ab20 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/PK_PARALLEL_EXPORT_CHUNKS_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index PK_PARALLEL_EXPORT_CHUNKS +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."PK_PARALLEL_EXPORT_CHUNKS" ON "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" ("TASK_NAME", "CHUNK_ID") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C00142356.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C00142356.sql new file mode 100644 index 0000000..00e7f9c --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C00142356.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C00142356 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C00142356" ON "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" ("A_PACKAGE_VERSION_TRACKING_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C00142356_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C00142356_1.sql new file mode 100644 index 0000000..00e7f9c --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C00142356_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C00142356 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C00142356" ON "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" ("A_PACKAGE_VERSION_TRACKING_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062744.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062744.sql new file mode 100644 index 0000000..e62f76a --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062744.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C0062744 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C0062744" ON "CT_MRDS"."A_FILE_MANAGER_CONFIG" ("ENVIRONMENT_ID", "CONFIG_VARIABLE") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062744_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062744_1.sql new file mode 100644 index 0000000..e62f76a --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062744_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C0062744 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C0062744" ON "CT_MRDS"."A_FILE_MANAGER_CONFIG" ("ENVIRONMENT_ID", "CONFIG_VARIABLE") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062752.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062752.sql new file mode 100644 index 0000000..832fcac --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062752.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C0062752 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C0062752" ON "CT_MRDS"."A_TABLE_STAT" ("A_TABLE_STAT_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062752_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062752_1.sql new file mode 100644 index 0000000..832fcac --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062752_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C0062752 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C0062752" ON "CT_MRDS"."A_TABLE_STAT" ("A_TABLE_STAT_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062756.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062756.sql new file mode 100644 index 0000000..23fd045 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062756.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C0062756 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C0062756" ON "CT_MRDS"."A_TABLE_STAT_HIST" ("A_TABLE_STAT_HIST_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062756_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062756_1.sql new file mode 100644 index 0000000..23fd045 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062756_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C0062756 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C0062756" ON "CT_MRDS"."A_TABLE_STAT_HIST" ("A_TABLE_STAT_HIST_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062776.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062776.sql new file mode 100644 index 0000000..c4205af --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062776.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C0062776 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C0062776" ON "CT_MRDS"."A_PROCESS_LOG" ("A_PROCESS_LOG_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062776_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062776_1.sql new file mode 100644 index 0000000..c4205af --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_C0062776_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index SYS_C0062776 +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_C0062776" ON "CT_MRDS"."A_PROCESS_LOG" ("A_PROCESS_LOG_KEY") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0000608162C00009__.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0000608162C00009__.sql new file mode 100644 index 0000000..1d75c06 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0000608162C00009__.sql @@ -0,0 +1,11 @@ +-------------------------------------------------------- +-- DDL for Index SYS_IL0000608162C00009$$ +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_IL0000608162C00009$$" ON "CT_MRDS"."A_PROCESS_LOG" + PCTFREE 10 INITRANS 2 MAXTRANS 255 + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" + PARALLEL (DEGREE 0 INSTANCES 0) ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0000609457C00004__.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0000609457C00004__.sql new file mode 100644 index 0000000..f5b508a --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0000609457C00004__.sql @@ -0,0 +1,11 @@ +-------------------------------------------------------- +-- DDL for Index SYS_IL0000609457C00004$$ +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_IL0000609457C00004$$" ON "CT_MRDS"."A_WORKFLOW_HISTORY_PROPERTY" + PCTFREE 10 INITRANS 2 MAXTRANS 255 + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" + PARALLEL (DEGREE 0 INSTANCES 0) ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0001159131C00010__.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0001159131C00010__.sql new file mode 100644 index 0000000..ce9ab7f --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/SYS_IL0001159131C00010__.sql @@ -0,0 +1,11 @@ +-------------------------------------------------------- +-- DDL for Index SYS_IL0001159131C00010$$ +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."SYS_IL0001159131C00010$$" ON "CT_MRDS"."A_PARALLEL_EXPORT_CHUNKS" + PCTFREE 10 INITRANS 2 MAXTRANS 255 + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" + PARALLEL (DEGREE 0 INSTANCES 0) ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_A_DEVO_REPLICA_MGMT_MOPDB.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_A_DEVO_REPLICA_MGMT_MOPDB.sql new file mode 100644 index 0000000..ed60d36 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_A_DEVO_REPLICA_MGMT_MOPDB.sql @@ -0,0 +1,52 @@ +-------------------------------------------------------- +-- DDL for Trigger TRG_A_DEVO_REPLICA_MGMT_MOPDB +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."TRG_A_DEVO_REPLICA_MGMT_MOPDB" +AFTER INSERT OR UPDATE OR DELETE + ON CT_MRDS.A_DEVO_REPLICA_MGMT_MOPDB + FOR EACH ROW +DECLARE + vAction VARCHAR2(100); +BEGIN + IF INSERTING THEN + vAction := 'INSERT'; + INSERT INTO CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:NEW.OWNER, :NEW.TABLE_NAME, :NEW.TABLE_ALIAS, + :NEW.LAST_RUN_ID, :NEW.LAST_START_TIME, :NEW.LAST_END_TIME, + :NEW.LAST_STATUS, :NEW.SAVE_MODE, :NEW.PARTITION_COLUMN, + :NEW.MAX_THREADS, :NEW.LAST_PROCESSED_KEY, vAction, + sysdate, 'MOPDB'); + ELSIF UPDATING THEN + vAction := 'UPDATE'; + INSERT INTO CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:NEW.OWNER, :NEW.TABLE_NAME, :NEW.TABLE_ALIAS, + :NEW.LAST_RUN_ID, :NEW.LAST_START_TIME, :NEW.LAST_END_TIME, + :NEW.LAST_STATUS, :NEW.SAVE_MODE, :NEW.PARTITION_COLUMN, + :NEW.MAX_THREADS, :NEW.LAST_PROCESSED_KEY, vAction, + sysdate, 'MOPDB'); + ELSIF DELETING THEN + vAction := 'DELETE'; + INSERT INTO CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:OLD.OWNER, :OLD.TABLE_NAME, :OLD.TABLE_ALIAS, + :OLD.LAST_RUN_ID, :OLD.LAST_START_TIME, :OLD.LAST_END_TIME, + :OLD.LAST_STATUS, :OLD.SAVE_MODE, :OLD.PARTITION_COLUMN, + :OLD.MAX_THREADS, :OLD.LAST_PROCESSED_KEY, vAction, + sysdate, 'MOPDB'); + END IF; +END; + +/ +ALTER TRIGGER "CT_MRDS"."TRG_A_DEVO_REPLICA_MGMT_MOPDB" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_A_DEVO_REPLICA_MGMT_MOPDB_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_A_DEVO_REPLICA_MGMT_MOPDB_1.sql new file mode 100644 index 0000000..ed60d36 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_A_DEVO_REPLICA_MGMT_MOPDB_1.sql @@ -0,0 +1,52 @@ +-------------------------------------------------------- +-- DDL for Trigger TRG_A_DEVO_REPLICA_MGMT_MOPDB +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."TRG_A_DEVO_REPLICA_MGMT_MOPDB" +AFTER INSERT OR UPDATE OR DELETE + ON CT_MRDS.A_DEVO_REPLICA_MGMT_MOPDB + FOR EACH ROW +DECLARE + vAction VARCHAR2(100); +BEGIN + IF INSERTING THEN + vAction := 'INSERT'; + INSERT INTO CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:NEW.OWNER, :NEW.TABLE_NAME, :NEW.TABLE_ALIAS, + :NEW.LAST_RUN_ID, :NEW.LAST_START_TIME, :NEW.LAST_END_TIME, + :NEW.LAST_STATUS, :NEW.SAVE_MODE, :NEW.PARTITION_COLUMN, + :NEW.MAX_THREADS, :NEW.LAST_PROCESSED_KEY, vAction, + sysdate, 'MOPDB'); + ELSIF UPDATING THEN + vAction := 'UPDATE'; + INSERT INTO CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:NEW.OWNER, :NEW.TABLE_NAME, :NEW.TABLE_ALIAS, + :NEW.LAST_RUN_ID, :NEW.LAST_START_TIME, :NEW.LAST_END_TIME, + :NEW.LAST_STATUS, :NEW.SAVE_MODE, :NEW.PARTITION_COLUMN, + :NEW.MAX_THREADS, :NEW.LAST_PROCESSED_KEY, vAction, + sysdate, 'MOPDB'); + ELSIF DELETING THEN + vAction := 'DELETE'; + INSERT INTO CT_MRDS.A_DEVO_REPLICA_MGMT_LOG (OWNER, TABLE_NAME, TABLE_ALIAS, + LAST_RUN_ID, LAST_START_TIME, LAST_END_TIME, + LAST_STATUS, SAVE_MODE, PARTITION_COLUMN, + MAX_THREADS, LAST_PROCESSED_KEY, ACTION, + LOG_DATE, LOG_SOURCE) + VALUES (:OLD.OWNER, :OLD.TABLE_NAME, :OLD.TABLE_ALIAS, + :OLD.LAST_RUN_ID, :OLD.LAST_START_TIME, :OLD.LAST_END_TIME, + :OLD.LAST_STATUS, :OLD.SAVE_MODE, :OLD.PARTITION_COLUMN, + :OLD.MAX_THREADS, :OLD.LAST_PROCESSED_KEY, vAction, + sysdate, 'MOPDB'); + END IF; +END; + +/ +ALTER TRIGGER "CT_MRDS"."TRG_A_DEVO_REPLICA_MGMT_MOPDB" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BIU_CHCK_TEMPLATE_TABLE_NAME.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BIU_CHCK_TEMPLATE_TABLE_NAME.sql new file mode 100644 index 0000000..665ff91 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BIU_CHCK_TEMPLATE_TABLE_NAME.sql @@ -0,0 +1,22 @@ +-------------------------------------------------------- +-- DDL for Trigger TRG_BIU_CHCK_TEMPLATE_TABLE_NAME +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."TRG_BIU_CHCK_TEMPLATE_TABLE_NAME" +BEFORE INSERT OR UPDATE ON "CT_MRDS"."A_COLUMN_DATE_FORMAT" +FOR EACH ROW +DECLARE + vCount NUMBER; +BEGIN + SELECT COUNT(*) + INTO vCount + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE TEMPLATE_TABLE_NAME = :NEW.TEMPLATE_TABLE_NAME; + + IF vCount = 0 THEN + RAISE_APPLICATION_ERROR(-20001, 'TEMPLATE_TABLE_NAME = '''||:NEW.TEMPLATE_TABLE_NAME||''' not exists in A_SOURCE_FILE_CONFIG.TEMPLATE_TABLE_NAME '); + END IF; +END; + +/ +ALTER TRIGGER "CT_MRDS"."TRG_BIU_CHCK_TEMPLATE_TABLE_NAME" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BIU_CHCK_TEMPLATE_TABLE_NAME_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BIU_CHCK_TEMPLATE_TABLE_NAME_1.sql new file mode 100644 index 0000000..665ff91 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BIU_CHCK_TEMPLATE_TABLE_NAME_1.sql @@ -0,0 +1,22 @@ +-------------------------------------------------------- +-- DDL for Trigger TRG_BIU_CHCK_TEMPLATE_TABLE_NAME +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."TRG_BIU_CHCK_TEMPLATE_TABLE_NAME" +BEFORE INSERT OR UPDATE ON "CT_MRDS"."A_COLUMN_DATE_FORMAT" +FOR EACH ROW +DECLARE + vCount NUMBER; +BEGIN + SELECT COUNT(*) + INTO vCount + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE TEMPLATE_TABLE_NAME = :NEW.TEMPLATE_TABLE_NAME; + + IF vCount = 0 THEN + RAISE_APPLICATION_ERROR(-20001, 'TEMPLATE_TABLE_NAME = '''||:NEW.TEMPLATE_TABLE_NAME||''' not exists in A_SOURCE_FILE_CONFIG.TEMPLATE_TABLE_NAME '); + END IF; +END; + +/ +ALTER TRIGGER "CT_MRDS"."TRG_BIU_CHCK_TEMPLATE_TABLE_NAME" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SOURCE_FILE_CONFIG_CHECK.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SOURCE_FILE_CONFIG_CHECK.sql new file mode 100644 index 0000000..788cc29 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SOURCE_FILE_CONFIG_CHECK.sql @@ -0,0 +1,59 @@ +-------------------------------------------------------- +-- DDL for Trigger TRG_BI_A_SOURCE_FILE_CONFIG_CHECK +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."TRG_BI_A_SOURCE_FILE_CONFIG_CHECK" +BEFORE INSERT ON CT_MRDS.A_SOURCE_FILE_CONFIG +FOR EACH ROW +DECLARE +-- NO_CONTAINER_FOR_INPUT EXCEPTION; + WRONG_CONTAINER_FOR_INPUT EXCEPTION; + CONTAINER_ALREADY_EXISTS EXCEPTION; + vCount PLS_INTEGER; + vContainerFileKey CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE; +BEGIN + + --Check if there is CONTAINER entity in A_SOURCE_FILE_CONFIG table + IF (:NEW.SOURCE_FILE_TYPE = 'INPUT' AND :NEW.CONTAINER_FILE_KEY IS NULL) THEN + :NEW.CONTAINER_FILE_KEY := CT_MRDS.FILE_MANAGER.GET_CONTAINER_SOURCE_FILE_CONFIG_KEY(:NEW.SOURCE_FILE_ID); +-- IF :NEW.CONTAINER_FILE_KEY is null THEN +-- RAISE NO_CONTAINER_FOR_INPUT; +-- END IF; + + -- Check if provided CONTAINER_FILE_KEY is the one which exists in the A_SOURCE_FILE_CONFIG table + ELSIF (:NEW.SOURCE_FILE_TYPE = 'INPUT' AND :NEW.CONTAINER_FILE_KEY IS NOT NULL) THEN + vContainerFileKey := CT_MRDS.FILE_MANAGER.GET_CONTAINER_SOURCE_FILE_CONFIG_KEY(:NEW.SOURCE_FILE_ID); + IF :NEW.CONTAINER_FILE_KEY <> vContainerFileKey THEN + RAISE WRONG_CONTAINER_FOR_INPUT; + END IF; + + -- Check if there is already a CONTAINER for provided SOURCE_FILE_ID + ELSIF (:NEW.SOURCE_FILE_TYPE = 'CONTAINER') THEN + SELECT count(*) + INTO vCount + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE :NEW.SOURCE_FILE_TYPE = 'CONTAINER' + AND SOURCE_FILE_ID = :NEW.SOURCE_FILE_ID; + + IF vCount > 0 THEN + RAISE CONTAINER_ALREADY_EXISTS; + END IF; + END IF; + SELECT CT_MRDS.A_SOURCE_FILE_CONFIG_KEY_SEQ.NEXTVAL INTO :NEW.A_SOURCE_FILE_CONFIG_KEY FROM DUAL; + +EXCEPTION +-- WHEN NO_CONTAINER_FOR_INPUT THEN +-- RAISE_APPLICATION_ERROR(-20011, 'Error while adding entity where SOURCE_FILE_TYPE = ''INPUT''' +-- ||CHR(13)||CHR(10)||'There is no A_SOURCE_FILE_CONFIG entity where SOURCE_FILE_ID = '''||:NEW.SOURCE_FILE_ID||''' AND SOURCE_FILE_TYPE = ''CONTAINER''' +-- ||CHR(13)||CHR(10)||'Add ''CONTAINER'' config entity before ''INPUT'' one'); + WHEN WRONG_CONTAINER_FOR_INPUT THEN + RAISE_APPLICATION_ERROR(-20012, 'Provided CONTAINER_FILE_KEY='||:NEW.CONTAINER_FILE_KEY||' is wrong' + ||CHR(13)||CHR(10)||'There is A_SOURCE_FILE_CONFIG entity where SOURCE_FILE_ID = '''||:NEW.SOURCE_FILE_ID||''' AND SOURCE_FILE_TYPE = ''CONTAINER''' + ||CHR(13)||CHR(10)||'Existing CONTAINER_FILE_KEY='||vContainerFileKey); + WHEN CONTAINER_ALREADY_EXISTS THEN + RAISE_APPLICATION_ERROR(-20013, 'Such CONTAINER already exists!' + ||CHR(13)||CHR(10)||'There is A_SOURCE_FILE_CONFIG entity where SOURCE_FILE_ID = '''||:NEW.SOURCE_FILE_ID||''' AND SOURCE_FILE_TYPE = ''CONTAINER'''); +END; + +/ +ALTER TRIGGER "CT_MRDS"."TRG_BI_A_SOURCE_FILE_CONFIG_CHECK" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SOURCE_FILE_CONFIG_CHECK_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SOURCE_FILE_CONFIG_CHECK_1.sql new file mode 100644 index 0000000..788cc29 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SOURCE_FILE_CONFIG_CHECK_1.sql @@ -0,0 +1,59 @@ +-------------------------------------------------------- +-- DDL for Trigger TRG_BI_A_SOURCE_FILE_CONFIG_CHECK +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."TRG_BI_A_SOURCE_FILE_CONFIG_CHECK" +BEFORE INSERT ON CT_MRDS.A_SOURCE_FILE_CONFIG +FOR EACH ROW +DECLARE +-- NO_CONTAINER_FOR_INPUT EXCEPTION; + WRONG_CONTAINER_FOR_INPUT EXCEPTION; + CONTAINER_ALREADY_EXISTS EXCEPTION; + vCount PLS_INTEGER; + vContainerFileKey CT_MRDS.A_SOURCE_FILE_CONFIG.A_SOURCE_FILE_CONFIG_KEY%TYPE; +BEGIN + + --Check if there is CONTAINER entity in A_SOURCE_FILE_CONFIG table + IF (:NEW.SOURCE_FILE_TYPE = 'INPUT' AND :NEW.CONTAINER_FILE_KEY IS NULL) THEN + :NEW.CONTAINER_FILE_KEY := CT_MRDS.FILE_MANAGER.GET_CONTAINER_SOURCE_FILE_CONFIG_KEY(:NEW.SOURCE_FILE_ID); +-- IF :NEW.CONTAINER_FILE_KEY is null THEN +-- RAISE NO_CONTAINER_FOR_INPUT; +-- END IF; + + -- Check if provided CONTAINER_FILE_KEY is the one which exists in the A_SOURCE_FILE_CONFIG table + ELSIF (:NEW.SOURCE_FILE_TYPE = 'INPUT' AND :NEW.CONTAINER_FILE_KEY IS NOT NULL) THEN + vContainerFileKey := CT_MRDS.FILE_MANAGER.GET_CONTAINER_SOURCE_FILE_CONFIG_KEY(:NEW.SOURCE_FILE_ID); + IF :NEW.CONTAINER_FILE_KEY <> vContainerFileKey THEN + RAISE WRONG_CONTAINER_FOR_INPUT; + END IF; + + -- Check if there is already a CONTAINER for provided SOURCE_FILE_ID + ELSIF (:NEW.SOURCE_FILE_TYPE = 'CONTAINER') THEN + SELECT count(*) + INTO vCount + FROM CT_MRDS.A_SOURCE_FILE_CONFIG + WHERE :NEW.SOURCE_FILE_TYPE = 'CONTAINER' + AND SOURCE_FILE_ID = :NEW.SOURCE_FILE_ID; + + IF vCount > 0 THEN + RAISE CONTAINER_ALREADY_EXISTS; + END IF; + END IF; + SELECT CT_MRDS.A_SOURCE_FILE_CONFIG_KEY_SEQ.NEXTVAL INTO :NEW.A_SOURCE_FILE_CONFIG_KEY FROM DUAL; + +EXCEPTION +-- WHEN NO_CONTAINER_FOR_INPUT THEN +-- RAISE_APPLICATION_ERROR(-20011, 'Error while adding entity where SOURCE_FILE_TYPE = ''INPUT''' +-- ||CHR(13)||CHR(10)||'There is no A_SOURCE_FILE_CONFIG entity where SOURCE_FILE_ID = '''||:NEW.SOURCE_FILE_ID||''' AND SOURCE_FILE_TYPE = ''CONTAINER''' +-- ||CHR(13)||CHR(10)||'Add ''CONTAINER'' config entity before ''INPUT'' one'); + WHEN WRONG_CONTAINER_FOR_INPUT THEN + RAISE_APPLICATION_ERROR(-20012, 'Provided CONTAINER_FILE_KEY='||:NEW.CONTAINER_FILE_KEY||' is wrong' + ||CHR(13)||CHR(10)||'There is A_SOURCE_FILE_CONFIG entity where SOURCE_FILE_ID = '''||:NEW.SOURCE_FILE_ID||''' AND SOURCE_FILE_TYPE = ''CONTAINER''' + ||CHR(13)||CHR(10)||'Existing CONTAINER_FILE_KEY='||vContainerFileKey); + WHEN CONTAINER_ALREADY_EXISTS THEN + RAISE_APPLICATION_ERROR(-20013, 'Such CONTAINER already exists!' + ||CHR(13)||CHR(10)||'There is A_SOURCE_FILE_CONFIG entity where SOURCE_FILE_ID = '''||:NEW.SOURCE_FILE_ID||''' AND SOURCE_FILE_TYPE = ''CONTAINER'''); +END; + +/ +ALTER TRIGGER "CT_MRDS"."TRG_BI_A_SOURCE_FILE_CONFIG_CHECK" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SRC_FILE_CFG_ARCH_VAL.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SRC_FILE_CFG_ARCH_VAL.sql new file mode 100644 index 0000000..fdda424 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SRC_FILE_CFG_ARCH_VAL.sql @@ -0,0 +1,36 @@ +-------------------------------------------------------- +-- DDL for Trigger TRG_BI_A_SRC_FILE_CFG_ARCH_VAL +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."TRG_BI_A_SRC_FILE_CFG_ARCH_VAL" +BEFORE INSERT OR UPDATE ON CT_MRDS.A_SOURCE_FILE_CONFIG +FOR EACH ROW +DECLARE + vErrorMsg VARCHAR2(1000); +BEGIN + -- Validate MINIMUM_AGE_MONTHS required for specific strategies + IF :NEW.ARCHIVAL_STRATEGY IN ('MINIMUM_AGE_MONTHS', 'HYBRID') + AND :NEW.MINIMUM_AGE_MONTHS IS NULL THEN + vErrorMsg := 'MINIMUM_AGE_MONTHS is required for ' || :NEW.ARCHIVAL_STRATEGY || ' strategy'; + RAISE_APPLICATION_ERROR(-20999, vErrorMsg); + END IF; + + -- Validate MINIMUM_AGE_MONTHS is non-negative (0 = current month only) + IF :NEW.MINIMUM_AGE_MONTHS IS NOT NULL + AND :NEW.MINIMUM_AGE_MONTHS < 0 THEN + RAISE_APPLICATION_ERROR(-20998, 'MINIMUM_AGE_MONTHS must be greater than or equal to 0'); + END IF; + + -- Warn if MINIMUM_AGE_MONTHS set but strategy doesn't use it + IF :NEW.MINIMUM_AGE_MONTHS IS NOT NULL + AND :NEW.ARCHIVAL_STRATEGY NOT IN ('MINIMUM_AGE_MONTHS', 'HYBRID') THEN + -- This is just a warning scenario - allow but could log + NULL; + END IF; + +EXCEPTION + WHEN OTHERS THEN + RAISE; +END; +/ +ALTER TRIGGER "CT_MRDS"."TRG_BI_A_SRC_FILE_CFG_ARCH_VAL" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SRC_FILE_CFG_ARCH_VAL_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SRC_FILE_CFG_ARCH_VAL_1.sql new file mode 100644 index 0000000..fdda424 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/TRG_BI_A_SRC_FILE_CFG_ARCH_VAL_1.sql @@ -0,0 +1,36 @@ +-------------------------------------------------------- +-- DDL for Trigger TRG_BI_A_SRC_FILE_CFG_ARCH_VAL +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TRIGGER "CT_MRDS"."TRG_BI_A_SRC_FILE_CFG_ARCH_VAL" +BEFORE INSERT OR UPDATE ON CT_MRDS.A_SOURCE_FILE_CONFIG +FOR EACH ROW +DECLARE + vErrorMsg VARCHAR2(1000); +BEGIN + -- Validate MINIMUM_AGE_MONTHS required for specific strategies + IF :NEW.ARCHIVAL_STRATEGY IN ('MINIMUM_AGE_MONTHS', 'HYBRID') + AND :NEW.MINIMUM_AGE_MONTHS IS NULL THEN + vErrorMsg := 'MINIMUM_AGE_MONTHS is required for ' || :NEW.ARCHIVAL_STRATEGY || ' strategy'; + RAISE_APPLICATION_ERROR(-20999, vErrorMsg); + END IF; + + -- Validate MINIMUM_AGE_MONTHS is non-negative (0 = current month only) + IF :NEW.MINIMUM_AGE_MONTHS IS NOT NULL + AND :NEW.MINIMUM_AGE_MONTHS < 0 THEN + RAISE_APPLICATION_ERROR(-20998, 'MINIMUM_AGE_MONTHS must be greater than or equal to 0'); + END IF; + + -- Warn if MINIMUM_AGE_MONTHS set but strategy doesn't use it + IF :NEW.MINIMUM_AGE_MONTHS IS NOT NULL + AND :NEW.ARCHIVAL_STRATEGY NOT IN ('MINIMUM_AGE_MONTHS', 'HYBRID') THEN + -- This is just a warning scenario - allow but could log + NULL; + END IF; + +EXCEPTION + WHEN OTHERS THEN + RAISE; +END; +/ +ALTER TRIGGER "CT_MRDS"."TRG_BI_A_SRC_FILE_CFG_ARCH_VAL" ENABLE; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/T_FILENAME.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/T_FILENAME.sql new file mode 100644 index 0000000..ed8da51 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/T_FILENAME.sql @@ -0,0 +1,14 @@ +-------------------------------------------------------- +-- DDL for Type T_FILENAME +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TYPE "CT_MRDS"."T_FILENAME" as object ( + FILENAME varchar2(200) + ,PATHNAME varchar2(800) + ,YEAR varchar2(4) + ,MONTH varchar2(2) + ); + +/ + + GRANT EXECUTE ON "CT_MRDS"."T_FILENAME" TO "MRDS_LOADER"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/T_FILENAMES.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/T_FILENAMES.sql new file mode 100644 index 0000000..179fc5b --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/T_FILENAMES.sql @@ -0,0 +1,7 @@ +-------------------------------------------------------- +-- DDL for Type T_FILENAMES +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE TYPE "CT_MRDS"."T_FILENAMES" is table of T_FILENAME; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UK_PKG_VERSION_TRACK.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UK_PKG_VERSION_TRACK.sql new file mode 100644 index 0000000..b53b69e --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UK_PKG_VERSION_TRACK.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index UK_PKG_VERSION_TRACK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."UK_PKG_VERSION_TRACK" ON "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" ("PACKAGE_OWNER", "PACKAGE_NAME", "TRACKING_DATE") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UK_PKG_VERSION_TRACK_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UK_PKG_VERSION_TRACK_1.sql new file mode 100644 index 0000000..b53b69e --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UK_PKG_VERSION_TRACK_1.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------- +-- DDL for Index UK_PKG_VERSION_TRACK +-------------------------------------------------------- + + CREATE UNIQUE INDEX "CT_MRDS"."UK_PKG_VERSION_TRACK" ON "CT_MRDS"."A_PACKAGE_VERSION_TRACKING" ("PACKAGE_OWNER", "PACKAGE_NAME", "TRACKING_DATE") + PCTFREE 10 INITRANS 20 MAXTRANS 255 COMPUTE STATISTICS + STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 + PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 + BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) + TABLESPACE "DATA" ; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UTL_RECOMP.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UTL_RECOMP.sql new file mode 100644 index 0000000..e59b5f3 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UTL_RECOMP.sql @@ -0,0 +1,5 @@ +-------------------------------------------------------- +-- DDL for Synonymn UTL_RECOMP +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE SYNONYM "PDBADMIN"."UTL_RECOMP" FOR "SYS"."UTL_RECOMP"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UTL_RECOMP_ERRORS.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UTL_RECOMP_ERRORS.sql new file mode 100644 index 0000000..beebb06 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/UTL_RECOMP_ERRORS.sql @@ -0,0 +1,5 @@ +-------------------------------------------------------- +-- DDL for Synonymn UTL_RECOMP_ERRORS +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE SYNONYM "PDBADMIN"."UTL_RECOMP_ERRORS" FOR "SYS"."UTL_RECOMP_ERRORS"; diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/WORKFLOW_MANAGER.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/WORKFLOW_MANAGER.sql new file mode 100644 index 0000000..d6711b1 --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/WORKFLOW_MANAGER.sql @@ -0,0 +1,105 @@ +-------------------------------------------------------- +-- DDL for Package WORKFLOW_MANAGER +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE PACKAGE "CT_MRDS"."WORKFLOW_MANAGER" +IS + + -- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH) + PACKAGE_VERSION CONSTANT VARCHAR2(10) := '1.7.1'; + PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-11-18 12:00:00'; + PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski'; + + -- Version History (Latest changes first) + VERSION_HISTORY CONSTANT VARCHAR2(4000) := + '1.7.1 (2025-11-18): Added SERVICE_NAME column with hardcoded ''ODS'' value to INIT_TASK function' || CHR(13)||CHR(10) || + '1.7.0 (2025-10-31): Added FINALISE_TASK_WITH_TARGET_INFO function for atomic task completion with target info' || CHR(13)||CHR(10) || + '1.6.0 (2025-10-31): Converted STORE_TASK_SOURCE_INFO and STORE_TASK_TARGET_INFO from procedures to functions returning sequence keys' || CHR(13)||CHR(10) || + '1.5.0 (2025-10-22): Added package versioning system using centralized ENV_MANAGER functions' || CHR(13)||CHR(10) || + '1.2.0 (2025-10-05): Added workflow property management (SET/GET_WORKFLOW_PROPERTY)' || CHR(13)||CHR(10) || + '1.0.0 (2025-09-10): Initial release with workflow and task lifecycle management'; + + -- Line break constant for consistent CRLF formatting across Windows environments + cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10); + + FUNCTION INIT_WORKFLOW(pServiceName IN VARCHAR2, pWorkflowRunId IN VARCHAR2, pWorkflowName in VARCHAR2) + RETURN NUMBER; + + PROCEDURE FINALISE_WORKFLOW(pWorkflowHistoryKey IN NUMBER, pWorkflowStatus IN VARCHAR2); + PROCEDURE FINALISE_WORKFLOW(pWorkflowHistoryKey IN NUMBER, pServiceName IN VARCHAR2, pWorkflowStatus IN VARCHAR2); + + FUNCTION INIT_TASK(pTaskRunId IN VARCHAR2, pTaskName in VARCHAR2, pWorkflowHistoryKey IN NUMBER) + RETURN NUMBER; + + PROCEDURE FINALISE_TASK(pTaskHistoryKey IN NUMBER, pTaskStatus IN VARCHAR2); + + FUNCTION STORE_TASK_SOURCE_INFO(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2, pNumRows IN NUMBER) + RETURN NUMBER; + + FUNCTION STORE_TASK_TARGET_INFO(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2, + pNumRowsApplied IN NUMBER, pNumRowsRejected IN NUMBER, + pLoadSuccessful IN VARCHAR2, pServiceName IN VARCHAR2) + RETURN NUMBER; + + FUNCTION FINALISE_TASK_WITH_TARGET_INFO(pTaskHistoryKey IN NUMBER, pTaskStatus IN VARCHAR2, + pTargetName IN VARCHAR2, pNumRowsApplied IN NUMBER, + pNumRowsRejected IN NUMBER, pLoadSuccessful IN VARCHAR2, + pServiceName IN VARCHAR2) + RETURN NUMBER; + + vpRunningStatus CT_MRDS.A_WORKFLOW_HISTORY.WORKFLOW_SUCCESSFUL%TYPE := 'R'; + + -- + -- Set and get information on workflow level + -- + PROCEDURE SET_WORKFLOW_PROPERTY( + pWorkflowHistoryKey IN NUMBER + ,pServiceName IN VARCHAR2 + ,pProperty IN VARCHAR2 + ,pValue IN VARCHAR2 + ); + + FUNCTION GET_WORKFLOW_PROPERTY( + pWorkflowHistoryKey IN NUMBER + ,pServiceName IN VARCHAR2 + ,pProperty IN VARCHAR2) + RETURN VARCHAR2; + + --------------------------------------------------------------------------------------------------------------------------- + -- PACKAGE VERSION MANAGEMENT FUNCTIONS + --------------------------------------------------------------------------------------------------------------------------- + + /** + * @name GET_VERSION + * @desc Returns the current version number of the WORKFLOW_MANAGER package. + * Uses semantic versioning format (MAJOR.MINOR.PATCH). + * @example SELECT WORKFLOW_MANAGER.GET_VERSION() FROM DUAL; + * @ex_rslt 1.5.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 WORKFLOW_MANAGER.GET_BUILD_INFO() FROM DUAL; + * @ex_rslt Package: WORKFLOW_MANAGER + * Version: 1.5.0 + * Build Date: 2025-10-22 17:00:00 + * Author: Grzegorz Michalski + **/ + FUNCTION GET_BUILD_INFO RETURN VARCHAR2; + + /** + * @name GET_VERSION_HISTORY + * @desc Returns complete version history with all releases and changes. + * Uses centralized ENV_MANAGER.FORMAT_VERSION_HISTORY function. + * @example SELECT WORKFLOW_MANAGER.GET_VERSION_HISTORY() FROM DUAL; + * @ex_rslt WORKFLOW_MANAGER Version History: + * 1.5.0 (2025-10-22): Added package versioning system... + **/ + FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2; + +END WORKFLOW_MANAGER; + +/ diff --git a/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/WORKFLOW_MANAGER_1.sql b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/WORKFLOW_MANAGER_1.sql new file mode 100644 index 0000000..1f70bbf --- /dev/null +++ b/MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/CT_MRDS/export/WORKFLOW_MANAGER_1.sql @@ -0,0 +1,221 @@ +-------------------------------------------------------- +-- DDL for Package Body WORKFLOW_MANAGER +-------------------------------------------------------- + + CREATE OR REPLACE EDITIONABLE PACKAGE BODY "CT_MRDS"."WORKFLOW_MANAGER" +IS + + FUNCTION INIT_WORKFLOW(pServiceName IN VARCHAR2, pWorkflowRunId IN VARCHAR2, pWorkflowName in VARCHAR2) + RETURN NUMBER + IS + vWorkflowHistoryKey NUMBER; + BEGIN + vWorkflowHistoryKey := A_WORKFLOW_HISTORY_KEY_SEQ.NEXTVAL; + INSERT INTO CT_MRDS.A_WORKFLOW_HISTORY (SERVICE_NAME, A_WORKFLOW_HISTORY_KEY, ORCHESTRATION_RUN_ID, + WORKFLOW_NAME, WORKFLOW_START, WORKFLOW_SUCCESSFUL) + VALUES (pServiceName, vWorkflowHistoryKey, pWorkflowRunId, + pWorkflowName, SYSTIMESTAMP, vpRunningStatus); + + return vWorkflowHistoryKey; + + END INIT_WORKFLOW; + + + -- + -- Overload without service name for backward compatability, to be cleaned up later + -- + PROCEDURE FINALISE_WORKFLOW(pWorkflowHistoryKey IN NUMBER, pWorkflowStatus IN VARCHAR2) + IS + BEGIN + FINALISE_WORKFLOW(pWorkflowHistoryKey, NULL, pWorkflowStatus); + END; + + PROCEDURE FINALISE_WORKFLOW(pWorkflowHistoryKey IN NUMBER, pServiceName IN VARCHAR2, pWorkflowStatus IN VARCHAR2) + IS + BEGIN + UPDATE CT_MRDS.A_WORKFLOW_HISTORY SET WORKFLOW_SUCCESSFUL = pWorkflowStatus, + WORKFLOW_END = SYSTIMESTAMP + WHERE A_WORKFLOW_HISTORY_KEY = pWorkflowHistoryKey + AND SERVICE_NAME = NVL(pServiceName,SERVICE_NAME); + END FINALISE_WORKFLOW; + + + FUNCTION INIT_TASK(pTaskRunId IN VARCHAR2, pTaskName in VARCHAR2, pWorkflowHistoryKey IN NUMBER) + RETURN NUMBER + IS + vTaskHistoryKey NUMBER; + BEGIN + vTaskHistoryKey := A_TASK_HISTORY_KEY_SEQ.NEXTVAL; + INSERT INTO CT_MRDS.A_TASK_HISTORY (A_TASK_HISTORY_KEY, TASK_RUN_ID, A_WORKFLOW_HISTORY_KEY, + TASK_NAME, TASK_START, TASK_SUCCESSFUL, SERVICE_NAME) + VALUES (vTaskHistoryKey, pTaskRunId, pWorkflowHistoryKey, + pTaskName, SYSTIMESTAMP, vpRunningStatus, 'ODS'); + + return vTaskHistoryKey; + + END INIT_TASK; + + + PROCEDURE FINALISE_TASK(pTaskHistoryKey IN NUMBER, pTaskStatus IN VARCHAR2) + IS + BEGIN + UPDATE CT_MRDS.A_TASK_HISTORY SET TASK_SUCCESSFUL = pTaskStatus, + TASK_END = SYSTIMESTAMP + WHERE A_TASK_HISTORY_KEY = pTaskHistoryKey; + END FINALISE_TASK; + + -- Internal helper function without COMMIT for use within other functions + FUNCTION STORE_TASK_SOURCE_INFO_INTERNAL(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2, pNumRows IN NUMBER) + RETURN NUMBER + IS + vTaskHistorySourceKey NUMBER; + BEGIN + vTaskHistorySourceKey := A_TASK_HISTORY_SOURCE_KEY_SEQ.NEXTVAL; + INSERT INTO CT_MRDS.A_TASK_HISTORY_SOURCE (A_TASK_HISTORY_SOURCE_KEY, A_TASK_HISTORY_KEY, + SOURCE_NAME, ROW_COUNT) + VALUES (vTaskHistorySourceKey, pTaskHistoryKey, + pSourceName, pNumRows); + RETURN vTaskHistorySourceKey; + END; + + FUNCTION STORE_TASK_SOURCE_INFO(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2, pNumRows IN NUMBER) + RETURN NUMBER + IS + vTaskHistorySourceKey NUMBER; + BEGIN + vTaskHistorySourceKey := STORE_TASK_SOURCE_INFO_INTERNAL(pTaskHistoryKey, pSourceName, pNumRows); + COMMIT; + RETURN vTaskHistorySourceKey; + END; + + -- Internal helper function without COMMIT for use within other functions + FUNCTION STORE_TASK_TARGET_INFO_INTERNAL(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2, + pNumRowsApplied IN NUMBER, pNumRowsRejected IN NUMBER, + pLoadSuccessful IN VARCHAR2, pServiceName IN VARCHAR2) + RETURN NUMBER + IS + vTaskHistoryTargetKey NUMBER; + BEGIN + vTaskHistoryTargetKey := A_TASK_HISTORY_TARGET_KEY_SEQ.NEXTVAL; + INSERT INTO CT_MRDS.A_TASK_HISTORY_TARGET (A_TASK_HISTORY_TARGET_KEY, A_TASK_HISTORY_KEY, + TARGET_NAME, ROW_COUNT_APPLIED, ROW_COUNT_REJECTED, + LOAD_SUCCESSFUL, SERVICE_NAME) + VALUES (vTaskHistoryTargetKey, pTaskHistoryKey, + pSourceName, pNumRowsApplied, pNumRowsRejected, + pLoadSuccessful, pServiceName); + RETURN vTaskHistoryTargetKey; + END; + + FUNCTION STORE_TASK_TARGET_INFO(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2, + pNumRowsApplied IN NUMBER, pNumRowsRejected IN NUMBER, + pLoadSuccessful IN VARCHAR2, pServiceName IN VARCHAR2) + RETURN NUMBER + IS + vTaskHistoryTargetKey NUMBER; + BEGIN + vTaskHistoryTargetKey := STORE_TASK_TARGET_INFO_INTERNAL( + pTaskHistoryKey, pSourceName, pNumRowsApplied, + pNumRowsRejected, pLoadSuccessful, pServiceName + ); + COMMIT; + RETURN vTaskHistoryTargetKey; + END; + + FUNCTION FINALISE_TASK_WITH_TARGET_INFO(pTaskHistoryKey IN NUMBER, pTaskStatus IN VARCHAR2, + pTargetName IN VARCHAR2, pNumRowsApplied IN NUMBER, + pNumRowsRejected IN NUMBER, pLoadSuccessful IN VARCHAR2, + pServiceName IN VARCHAR2) + RETURN NUMBER + IS + vTaskHistoryTargetKey NUMBER; + BEGIN + -- Store target information using internal function (without COMMIT) + vTaskHistoryTargetKey := STORE_TASK_TARGET_INFO_INTERNAL( + pTaskHistoryKey => pTaskHistoryKey, + pSourceName => pTargetName, + pNumRowsApplied => pNumRowsApplied, + pNumRowsRejected => pNumRowsRejected, + pLoadSuccessful => pLoadSuccessful, + pServiceName => pServiceName + ); + + -- Finalize the task using existing procedure (no COMMIT in procedure) + FINALISE_TASK(pTaskHistoryKey, pTaskStatus); + + -- Single COMMIT for the entire atomic operation + COMMIT; + + RETURN vTaskHistoryTargetKey; + END; + + PROCEDURE SET_WORKFLOW_PROPERTY( + pWorkflowHistoryKey IN NUMBER + ,pServiceName IN VARCHAR2 + ,pProperty IN VARCHAR2 + ,pValue IN VARCHAR2 + ) IS + BEGIN + INSERT INTO CT_MRDS.A_WORKFLOW_HISTORY_PROPERTY (A_WORKFLOW_HISTORY_KEY, SERVICE_NAME, PROPERTY, VALUE) + VALUES (pWorkflowHistoryKey, pServiceName, pProperty, pValue); + END; + + FUNCTION GET_WORKFLOW_PROPERTY( + pWorkflowHistoryKey IN NUMBER + ,pServiceName IN VARCHAR2 + ,pProperty IN VARCHAR2 + ) RETURN VARCHAR2 + IS + vValue CT_MRDS.A_WORKFLOW_HISTORY_PROPERTY.VALUE%TYPE; + BEGIN + SELECT VALUE + INTO vValue + FROM CT_MRDS.A_WORKFLOW_HISTORY_PROPERTY + WHERE A_WORKFLOW_HISTORY_KEY = pWorkflowHistoryKey + AND SERVICE_NAME = pServiceName + AND PROPERTY = pProperty; + + RETURN vValue; + END; + + ---------------------------------------------------------------------------------------------------- + -- 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 ENV_MANAGER.GET_PACKAGE_VERSION_INFO( + pPackageName => 'WORKFLOW_MANAGER', + pVersion => PACKAGE_VERSION, + pBuildDate => PACKAGE_BUILD_DATE, + pAuthor => PACKAGE_AUTHOR + ); + END GET_BUILD_INFO; + + ---------------------------------------------------------------------------------------------------- + + FUNCTION GET_VERSION_HISTORY + RETURN VARCHAR2 + IS + BEGIN + RETURN ENV_MANAGER.FORMAT_VERSION_HISTORY( + pPackageName => 'WORKFLOW_MANAGER', + pVersionHistory => VERSION_HISTORY + ); + END GET_VERSION_HISTORY; + + ---------------------------------------------------------------------------------------------------- + +END WORKFLOW_MANAGER; + +/