diff --git a/MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/02_MARS_1409_POSTHOOK_diagnose_workflow_key_status.sql b/MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/02_MARS_1409_POSTHOOK_diagnose_workflow_key_status.sql index be8c35a..0ea2070 100644 --- a/MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/02_MARS_1409_POSTHOOK_diagnose_workflow_key_status.sql +++ b/MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/02_MARS_1409_POSTHOOK_diagnose_workflow_key_status.sql @@ -46,6 +46,16 @@ DECLARE cMaxPrint CONSTANT NUMBER := 1000; vPrinted NUMBER; + FUNCTION IS_EXTERNAL_TABLE_EMPTY_ERROR( + pSqlCode NUMBER, + pSqlErrm VARCHAR2 + ) RETURN BOOLEAN + IS + BEGIN + RETURN pSqlCode IN (-29913, -29400) + OR INSTR(pSqlErrm, 'KUP-05002') > 0; + END; + BEGIN FOR config_rec IN ( @@ -79,7 +89,7 @@ BEGIN INTO vTableExists; EXCEPTION WHEN OTHERS THEN - IF SQLCODE = -29913 THEN + IF IS_EXTERNAL_TABLE_EMPTY_ERROR(SQLCODE, SQLERRM) THEN vBucketEmpty := TRUE; ELSE RAISE; @@ -97,63 +107,80 @@ BEGIN vInBothNoKey := 0; ELSE - -- ---------------------------------------------------------------- - -- [A] In ODS bucket but NOT in A_SOURCE_FILE_RECEIVED - -- ---------------------------------------------------------------- - EXECUTE IMMEDIATE - 'SELECT COUNT(DISTINCT t.file$name) ' || - 'FROM ' || vTableName || ' t ' || - 'WHERE t.file$name IS NOT NULL ' || - ' AND NOT EXISTS ( ' || - ' SELECT 1 FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || - ' WHERE sfr.SOURCE_FILE_NAME = t.file$name ' || - ' AND sfr.A_SOURCE_FILE_CONFIG_KEY = :1)' - INTO vOnlyInBucket - USING config_rec.A_SOURCE_FILE_CONFIG_KEY; + BEGIN + -- ---------------------------------------------------------------- + -- [A] In ODS bucket but NOT in A_SOURCE_FILE_RECEIVED + -- ---------------------------------------------------------------- + EXECUTE IMMEDIATE + 'SELECT COUNT(DISTINCT t.file$name) ' || + 'FROM ' || vTableName || ' t ' || + 'WHERE t.file$name IS NOT NULL ' || + ' AND NOT EXISTS ( ' || + ' SELECT 1 FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || + ' WHERE sfr.SOURCE_FILE_NAME = t.file$name ' || + ' AND sfr.A_SOURCE_FILE_CONFIG_KEY = :1)' + INTO vOnlyInBucket + USING config_rec.A_SOURCE_FILE_CONFIG_KEY; - -- ---------------------------------------------------------------- - -- [B] In A_SOURCE_FILE_RECEIVED (targeted statuses) but NOT in ODS bucket - -- ---------------------------------------------------------------- - EXECUTE IMMEDIATE - 'SELECT COUNT(*) ' || - 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || - 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || - ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || - ' AND NOT EXISTS ( ' || - ' SELECT 1 FROM ' || vTableName || ' t ' || - ' WHERE t.file$name = sfr.SOURCE_FILE_NAME)' - INTO vOnlyInDB - USING config_rec.A_SOURCE_FILE_CONFIG_KEY; + -- ---------------------------------------------------------------- + -- [B] In A_SOURCE_FILE_RECEIVED (targeted statuses) but NOT in ODS bucket + -- ---------------------------------------------------------------- + EXECUTE IMMEDIATE + 'SELECT COUNT(*) ' || + 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || + 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || + ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || + ' AND NOT EXISTS ( ' || + ' SELECT 1 FROM ' || vTableName || ' t ' || + ' WHERE t.file$name = sfr.SOURCE_FILE_NAME)' + INTO vOnlyInDB + USING config_rec.A_SOURCE_FILE_CONFIG_KEY; - -- ---------------------------------------------------------------- - -- [C] In both, A_WORKFLOW_HISTORY_KEY IS NOT NULL - -- ---------------------------------------------------------------- - EXECUTE IMMEDIATE - 'SELECT COUNT(DISTINCT sfr.A_SOURCE_FILE_RECEIVED_KEY) ' || - 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || - 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || - ' AND sfr.A_WORKFLOW_HISTORY_KEY IS NOT NULL ' || - ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || - ' AND EXISTS ( ' || - ' SELECT 1 FROM ' || vTableName || ' t ' || - ' WHERE t.file$name = sfr.SOURCE_FILE_NAME)' - INTO vInBothWithKey - USING config_rec.A_SOURCE_FILE_CONFIG_KEY; + -- ---------------------------------------------------------------- + -- [C] In both, A_WORKFLOW_HISTORY_KEY IS NOT NULL + -- ---------------------------------------------------------------- + EXECUTE IMMEDIATE + 'SELECT COUNT(DISTINCT sfr.A_SOURCE_FILE_RECEIVED_KEY) ' || + 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || + 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || + ' AND sfr.A_WORKFLOW_HISTORY_KEY IS NOT NULL ' || + ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || + ' AND EXISTS ( ' || + ' SELECT 1 FROM ' || vTableName || ' t ' || + ' WHERE t.file$name = sfr.SOURCE_FILE_NAME)' + INTO vInBothWithKey + USING config_rec.A_SOURCE_FILE_CONFIG_KEY; - -- ---------------------------------------------------------------- - -- [D] In both, A_WORKFLOW_HISTORY_KEY IS NULL - -- ---------------------------------------------------------------- - EXECUTE IMMEDIATE - 'SELECT COUNT(DISTINCT sfr.A_SOURCE_FILE_RECEIVED_KEY) ' || - 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || - 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || - ' AND sfr.A_WORKFLOW_HISTORY_KEY IS NULL ' || - ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || - ' AND EXISTS ( ' || - ' SELECT 1 FROM ' || vTableName || ' t ' || - ' WHERE t.file$name = sfr.SOURCE_FILE_NAME)' - INTO vInBothNoKey - USING config_rec.A_SOURCE_FILE_CONFIG_KEY; + -- ---------------------------------------------------------------- + -- [D] In both, A_WORKFLOW_HISTORY_KEY IS NULL + -- ---------------------------------------------------------------- + EXECUTE IMMEDIATE + 'SELECT COUNT(DISTINCT sfr.A_SOURCE_FILE_RECEIVED_KEY) ' || + 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || + 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || + ' AND sfr.A_WORKFLOW_HISTORY_KEY IS NULL ' || + ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || + ' AND EXISTS ( ' || + ' SELECT 1 FROM ' || vTableName || ' t ' || + ' WHERE t.file$name = sfr.SOURCE_FILE_NAME)' + INTO vInBothNoKey + USING config_rec.A_SOURCE_FILE_CONFIG_KEY; + EXCEPTION + WHEN OTHERS THEN + IF IS_EXTERNAL_TABLE_EMPTY_ERROR(SQLCODE, SQLERRM) THEN + vBucketEmpty := TRUE; + vOnlyInBucket := 0; + SELECT COUNT(*) INTO vOnlyInDB + FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr + WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = config_rec.A_SOURCE_FILE_CONFIG_KEY + AND sfr.PROCESSING_STATUS IN ('VALIDATED','READY_FOR_INGESTION','INGESTED','ARCHIVED','ARCHIVED_AND_TRASHED','ARCHIVED_AND_PURGED'); + vInBothWithKey := 0; + vInBothNoKey := 0; + DBMS_OUTPUT.PUT_LINE(' NOTE: ODS bucket became empty/inaccessible during diagnostics for ' || vTableName || '. Falling back to DB-only counts for [B].'); + ELSE + RAISE; + END IF; + END; END IF; -- vBucketEmpty @@ -204,16 +231,43 @@ BEGIN vConfigsWithIssues := vConfigsWithIssues + 1; DBMS_OUTPUT.PUT_LINE(' [B] Registered files not found in bucket:'); vPrinted := 0; - OPEN vRefCursor FOR - 'SELECT sfr.SOURCE_FILE_NAME, sfr.PROCESSING_STATUS, sfr.A_WORKFLOW_HISTORY_KEY ' || - 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || - 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || - ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || - ' AND NOT EXISTS ( ' || - ' SELECT 1 FROM ' || vTableName || ' t ' || - ' WHERE t.file$name = sfr.SOURCE_FILE_NAME) ' || - 'ORDER BY sfr.SOURCE_FILE_NAME' - USING config_rec.A_SOURCE_FILE_CONFIG_KEY; + BEGIN + IF vBucketEmpty THEN + OPEN vRefCursor FOR + 'SELECT sfr.SOURCE_FILE_NAME, sfr.PROCESSING_STATUS, sfr.A_WORKFLOW_HISTORY_KEY ' || + 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || + 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || + ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || + 'ORDER BY sfr.SOURCE_FILE_NAME' + USING config_rec.A_SOURCE_FILE_CONFIG_KEY; + ELSE + OPEN vRefCursor FOR + 'SELECT sfr.SOURCE_FILE_NAME, sfr.PROCESSING_STATUS, sfr.A_WORKFLOW_HISTORY_KEY ' || + 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || + 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || + ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || + ' AND NOT EXISTS ( ' || + ' SELECT 1 FROM ' || vTableName || ' t ' || + ' WHERE t.file$name = sfr.SOURCE_FILE_NAME) ' || + 'ORDER BY sfr.SOURCE_FILE_NAME' + USING config_rec.A_SOURCE_FILE_CONFIG_KEY; + END IF; + EXCEPTION + WHEN OTHERS THEN + IF IS_EXTERNAL_TABLE_EMPTY_ERROR(SQLCODE, SQLERRM) THEN + vBucketEmpty := TRUE; + DBMS_OUTPUT.PUT_LINE(' NOTE: Skipping ODS anti-join details due to empty/inaccessible external table for ' || vTableName || '.'); + OPEN vRefCursor FOR + 'SELECT sfr.SOURCE_FILE_NAME, sfr.PROCESSING_STATUS, sfr.A_WORKFLOW_HISTORY_KEY ' || + 'FROM CT_MRDS.A_SOURCE_FILE_RECEIVED sfr ' || + 'WHERE sfr.A_SOURCE_FILE_CONFIG_KEY = :1 ' || + ' AND sfr.PROCESSING_STATUS IN (''VALIDATED'',''READY_FOR_INGESTION'',''INGESTED'',''ARCHIVED'',''ARCHIVED_AND_TRASHED'',''ARCHIVED_AND_PURGED'') ' || + 'ORDER BY sfr.SOURCE_FILE_NAME' + USING config_rec.A_SOURCE_FILE_CONFIG_KEY; + ELSE + RAISE; + END IF; + END; LOOP DECLARE vStatus VARCHAR2(50); diff --git a/MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/install_mars1409_posthook.sql b/MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/install_mars1409_posthook.sql index bc71dfe..45d6723 100644 --- a/MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/install_mars1409_posthook.sql +++ b/MARS_Packages/REL02_POST/MARS-1409-POSTHOOK/install_mars1409_posthook.sql @@ -53,6 +53,43 @@ END; / WHENEVER SQLERROR CONTINUE +PROMPT +PROMPT ============================================================================ +PROMPT PREREQUISITE CHECK: Verifying MARS-1409 objects +PROMPT ============================================================================ +WHENEVER SQLERROR EXIT SQL.SQLCODE +DECLARE + vColCount NUMBER; + vTableCount NUMBER; +BEGIN + SELECT COUNT(*) + INTO vColCount + FROM ALL_TAB_COLUMNS + WHERE OWNER = 'CT_MRDS' + AND TABLE_NAME = 'A_SOURCE_FILE_RECEIVED' + AND COLUMN_NAME = 'A_WORKFLOW_HISTORY_KEY'; + + IF vColCount = 0 THEN + RAISE_APPLICATION_ERROR(-20001, + 'Prerequisite failed: CT_MRDS.A_SOURCE_FILE_RECEIVED.A_WORKFLOW_HISTORY_KEY not found. Install MARS-1409 first (or do not run POSTHOOK after rollback).'); + END IF; + + SELECT COUNT(*) + INTO vTableCount + FROM ALL_TABLES + WHERE OWNER = 'CT_MRDS' + AND TABLE_NAME = 'A_WORKFLOW_HISTORY'; + + IF vTableCount = 0 THEN + RAISE_APPLICATION_ERROR(-20002, + 'Prerequisite failed: CT_MRDS.A_WORKFLOW_HISTORY table not found.'); + END IF; + + DBMS_OUTPUT.PUT_LINE('OK: Prerequisites satisfied (MARS-1409 schema changes detected).'); +END; +/ +WHENEVER SQLERROR CONTINUE + PROMPT PROMPT ============================================================================ PROMPT STEP 1: Backfill A_WORKFLOW_HISTORY_KEY for existing records