MINI MINI MANI MO

Path : /opt/oracle/product/18c/dbhomeXE/rdbms/admin/
File Upload :
Current File : //opt/oracle/product/18c/dbhomeXE/rdbms/admin/utltz_upg_check.sql

Rem
Rem $Header: rdbms/admin/utltz_upg_check.sql /main/4 2017/09/08 16:58:12 huagli Exp $
Rem
Rem utltz_upg_check.sql
Rem
Rem Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
Rem
Rem    NAME
Rem      utltz_upg_check.sql - TIME ZONE Upgrade Check Script
Rem                            (for 11gR2 or higher)
Rem
Rem    DESCRIPTION
Rem      This script prepares a database to update the database to the highest
Rem      installed timezone definitions using the utltz_upg_apply.sql script.
Rem
Rem    NOTES
Rem      * This script must be run using SQL*PLUS from the database home.
Rem      * This script must be connected AS SYSDBA to run.
Rem      * The database need to be 11.2.0.1 or higher.
Rem      * The database will NOT be restarted .
Rem      * NO downtime is needed for this script.
Rem   	 * This script takes no arguments.
Rem      * This script WILL exit SQL*PLUS when an error is detected
Rem      * The dba_recyclebin WILL be purged.
Rem      * This script will check for all known issues at time of last update.
Rem      * An UPG_TZV table will be created.
Rem      * TZ_VERSION in Registry$database will be updated with current version.
Rem      * The utltz_upg_apply.sql script depends on this script.
Rem      * The script will write a line into the alert.log when ending successfully.
Rem
Rem    BEGIN SQL_FILE_METADATA
Rem    SQL_SOURCE_FILE: rdbms/admin/utltz_upg_check.sql
Rem    SQL_SHIPPED_FILE: rdbms/admin/utltz_upg_check.sql
Rem    SQL_PHASE: UPGRADE
Rem    SQL_STARTUP_MODE: NORMAL
Rem    SQL_IGNORABLE_ERRORS: NONE
Rem    SQL_CALLING_FILE:
Rem    END SQL_FILE_METADATA
Rem
Rem    MODIFIED   (MM/DD/YY)
Rem    huagli      08/31/17 - 26721930: DB version change
Rem    huagli      06/09/17 - 25988996: CDB/PDB RAC check and various cleanup
Rem    huagli      04/07/17 - 25856520: handle PDB name correctly
Rem    huagli      01/31/17 - renamed to utltz_upg_check.sql and added to shiphome
Rem    gvermeir    08/22/14 - updated to handle CDB/PDB (Multitenant) DST updates
Rem    gvermeir    07/10/14 - changed 1882 in DST$ERROR_TABLE from error to warning
Rem    gvermeir    05/23/14 - changed detection of Bug 14732853 to avoid using DBA_TSTZ_TAB_COLS
Rem    gvermeir    03/17/14 - logging of time makes more sense in minutes
Rem    gvermeir    03/04/14 - known bug detection is now faster on some dbs
Rem    gvermeir    02/20/14 - added logging to alert.log
Rem    gvermeir    12/23/13 - minor changes on error handling
Rem    gvermeir    09/20/13 - enhanced error checking and handling
Rem    gvermeir    06/12/13 - enhanced storing of found result
Rem    gvermeir    06/07/13 - corrected check for bug 14732853
Rem    gvermeir    05/16/13 - Additional check added/typos fixed
Rem    gvermeir    05/13/13 - Initial internal release
Rem    gvermeir    04/23/13 - created
Rem

@@?/rdbms/admin/sqlsessstart.sql

SET TERMOUT OFF
SET SERVEROUTPUT ON
SET FEEDBACK OFF

-- Get current time to track TZ upgrade time
VARIABLE V_TIME NUMBER
EXEC :V_TIME := DBMS_UTILITY.GET_TIME

-- Alter session to avoid performance issues
ALTER SESSION SET NLS_SORT = 'BINARY';

-- Set client_info so one can use: 
-- SELECT ... FROM v$session WHERE client_info = 'upg_tzv';
EXEC DBMS_APPLICATION_INFO.SET_CLIENT_INFO('upg_tzv');
WHENEVER SQLERROR EXIT

-- Faster selects on ALL_TSTZ_TAB_COLS
ALTER SESSION SET "_with_subquery" = 'MATERIALIZE';

SET TERMOUT ON

-- Check if user is SYS
DECLARE
   v_checkvar1 VARCHAR2(10 CHAR);
BEGIN
   EXECUTE IMMEDIATE
     'SELECT SUBSTR(SYS_CONTEXT(''USERENV'',''CURRENT_USER''), 1, 10) 
      FROM dual'
   INTO v_checkvar1;

   IF v_checkvar1 = 'SYS' THEN
     NULL;
   ELSE
     DBMS_OUTPUT.PUT_LINE('ERROR: Current connection is not a ' ||
                          'sysdba connection!');
     RAISE_APPLICATION_ERROR(-20001, 'Stopping script - see previous message ...');
   END IF;
END;
/

WHENEVER SQLERROR CONTINUE

-- Give some info
EXEC DBMS_OUTPUT.PUT_LINE('INFO: Starting with RDBMS DST update preparation.' );
EXEC DBMS_OUTPUT.PUT_LINE('INFO: NO actual RDBMS DST update will be done by this script.' );
EXEC DBMS_OUTPUT.PUT_LINE('INFO: If an ERROR occurs the script will EXIT sqlplus.' );
EXEC DBMS_OUTPUT.PUT_LINE('INFO: Doing checks for known issues ...' );

-- All pre-checks
DECLARE
  V_DBVERSION VARCHAR2(8 CHAR);
  V_ISPDB     VARCHAR2(3 CHAR);
  V_OLDDBTZV  NUMBER;
  V_CHECKNUM1 NUMBER;
  V_CHECKNUM2 NUMBER;
  V_CHECKVAR1 VARCHAR2(128 CHAR);
  V_CHECKVAR2 VARCHAR2(10 CHAR);
BEGIN
  -- Make sure that only Release 11gR2 and up uses this script
  BEGIN
    BEGIN
      EXECUTE IMMEDIATE 'SELECT SUBSTR(version, 1, 8) FROM v$instance' INTO V_DBVERSION;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: VERSION FROM V$INSTANCE gives no rows.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Do an manual update and checks as documented in ');
      DBMS_OUTPUT.PUT_LINE('ERROR: note 977512.1 for 11gR2 or note 1509653.1 for 12c.');
      RAISE_APPLICATION_ERROR(-20010, 'Stopping script - see previous message ...');
    END;
    IF SUBSTR(V_DBVERSION,1,6) IN 
       ('8.1.7.','8.1.6.','8.1.5.','8.0.6.','8.0.5.','8.0.4.',
        '9.0.1.','9.2.0.','10.1.0','10.2.0','11.1.0') THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: This script cannot be used in Release ' || V_DBVERSION);
      DBMS_OUTPUT.PUT_LINE('ERROR: Please see note 412160.1 for the relevant note ');
      DBMS_OUTPUT.PUT_LINE('ERROR: when applying a DST patch to a database. ');
      DBMS_OUTPUT.PUT_LINE('ERROR: When upgrading to 11.2 or higher you need to run ' );
      DBMS_OUTPUT.PUT_LINE('ERROR: the utltz_upg_check.sql and utltz_upg_apply(_pdb).sql scripts ' );
      DBMS_OUTPUT.PUT_LINE('ERROR: AFTER the RDBMS version upgrade. ' );
      RAISE_APPLICATION_ERROR(-20011, 'Stopping script - see previous message ...');
    ELSE
      DBMS_OUTPUT.PUT_LINE('INFO: Database version is '|| V_DBVERSION || ' .');
    END IF;
  END;

  -- check if DB is READ WRITE 
  BEGIN
    EXECUTE IMMEDIATE 'SELECT open_mode FROM v$database' INTO V_CHECKVAR2;
    IF V_CHECKVAR2 != TO_CHAR('READ WRITE') THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: This database is in ' || V_CHECKVAR2 ||' mode.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Please restart the database READ WRITE mode ');
      RAISE_APPLICATION_ERROR(-20021, 'Stopping script - see previous message ...');
    END IF;
  END;

  -- check if 12c database is Multitenant or not and warn when updating CDB$ROOT for open PDBs
  V_CHECKVAR1 := SUBSTR(V_DBVERSION, 1, 4);
  BEGIN
    IF V_CHECKVAR1 >= '12.1' THEN
      EXECUTE IMMEDIATE 'SELECT cdb FROM v$database' INTO V_CHECKVAR2;
      IF V_CHECKVAR2 = TO_CHAR('NO') THEN
        V_ISPDB := TO_CHAR('NO');
      ELSE
        DBMS_OUTPUT.PUT_LINE('INFO: This database is a Multitenant database.');
        EXECUTE IMMEDIATE 'SELECT SYS_CONTEXT(''USERENV'',''CON_NAME'') FROM dual' INTO V_CHECKVAR1;
        IF V_CHECKVAR1 = TO_CHAR('CDB$ROOT') THEN
          DBMS_OUTPUT.PUT_LINE('INFO: Current container is CDB$ROOT .');		
          DBMS_OUTPUT.PUT_LINE('INFO: Updating the RDBMS DST version of the CDB / CDB$ROOT database ');
          DBMS_OUTPUT.PUT_LINE('INFO: will NOT update the RDBMS DST version of PDB databases in this CDB.');
          V_ISPDB := TO_CHAR('NO');
          EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM v$pdbs
                             WHERE name != TO_CHAR(''PDB$SEED'') AND
                                   open_mode != TO_CHAR(''MOUNTED'')' INTO V_CHECKNUM1;
          IF V_CHECKNUM1 = TO_NUMBER('0') THEN
            DBMS_OUTPUT.PUT_LINE('INFO: There are no open PDBs .');
          ELSE
            DBMS_OUTPUT.PUT_LINE('WARNING: There are '|| V_CHECKNUM1 ||' open PDBs .');
            DBMS_OUTPUT.PUT_LINE('WARNING: They will be closed when running utltz_upg_apply.sql .');
          END IF;
        ELSE
           DBMS_OUTPUT.PUT_LINE('INFO: This database is a PDB.');
           DBMS_OUTPUT.PUT_LINE('INFO: Current PDB is '|| V_CHECKVAR1 ||' .');
           V_ISPDB := TO_CHAR('YES');
        END IF;
      END IF;
    ELSE
      V_ISPDB := TO_CHAR('NO');
    END IF;
  END;

  -- check if DST_UPGRADE_STATE is NONE
  BEGIN
    BEGIN
      EXECUTE IMMEDIATE 'SELECT SUBSTR(property_value, 1, 10)
                         FROM database_properties
                         WHERE property_name = ''DST_UPGRADE_STATE''' 
      INTO V_CHECKVAR1;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: DST_PRIMARY_TT_VERSION FROM DATABASE_PROPERTIES gives no rows.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Do an manual update and checks as documented in ');
      DBMS_OUTPUT.PUT_LINE('ERROR: Note 977512.1 for 11gR2 or Note 1509653.1 for 12c.');
      RAISE_APPLICATION_ERROR(-20031, 'Stopping script - see previous message ...');
    END;
    IF V_CHECKVAR1 = TO_CHAR('NONE') THEN
      NULL;
    ELSIF V_CHECKVAR1 = TO_CHAR('PREPARE') THEN
      DBMS_OUTPUT.PUT_LINE('WARNING: Current DST_UPGRADE_STATE is '|| V_CHECKVAR1 || ' !');
      DBMS_OUTPUT.PUT_LINE('WARNING: DST_UPGRADE_STATE in DATABASE_PROPERTIES needs to be NONE ');
      DBMS_OUTPUT.PUT_LINE('WARNING: before running utltz_upg_check.sql.');
      DBMS_OUTPUT.PUT_LINE('WARNING: Trying to end PREPARE window and then continue');
      DBMS_DST.END_PREPARE;
      -- if this fails it will error out in next Check if DST_SECONDARY_TT_VERSION is zero check
    ELSIF V_CHECKVAR1 = TO_CHAR('DATAPUMP') THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: Current DST_UPGRADE_STATE is '|| V_CHECKVAR1 || ' !');
      DBMS_OUTPUT.PUT_LINE('ERROR: DST_UPGRADE_STATE in DATABASE_PROPERTIES needs to be NONE ');
      DBMS_OUTPUT.PUT_LINE('ERROR: before running utltz_upg_check.sql.');
      DBMS_OUTPUT.PUT_LINE('ERROR: wait until the datapump load is done or check ');
      DBMS_OUTPUT.PUT_LINE('ERROR: Note 336014.1 How To Cleanup Orphaned DataPump Jobs In DBA_DATAPUMP_JOBS ?');
      RAISE_APPLICATION_ERROR(-20032, 'Stopping script - see previous message ...');
    ELSIF V_CHECKVAR1 = TO_CHAR('UPGRADE') THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: Current DST_UPGRADE_STATE is '|| V_CHECKVAR1 || ' !');
      DBMS_OUTPUT.PUT_LINE('ERROR: DST_UPGRADE_STATE in DATABASE_PROPERTIES needs to be NONE ');
      DBMS_OUTPUT.PUT_LINE('ERROR: before running utltz_upg_check.sql.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Check if another DBA is doing a DST upgrade.');
      DBMS_OUTPUT.PUT_LINE('ERROR: If not, then do the checks as documented in point 3 ');
      DBMS_OUTPUT.PUT_LINE('ERROR: of Note 977512.1 for 11gR2 or Note 1509653.1 for 12c.');
      RAISE_APPLICATION_ERROR(-20033, 'Stopping script - see previous message ...');
    ELSE
      DBMS_OUTPUT.PUT_LINE('ERROR: Current DST_UPGRADE_STATE is '|| V_CHECKVAR1 || ' !');
      DBMS_OUTPUT.PUT_LINE('ERROR: DST_UPGRADE_STATE in DATABASE_PROPERTIES needs to be NONE ');
      DBMS_OUTPUT.PUT_LINE('ERROR: before running utltz_upg_check.sql.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Do the checks as documented in point 3 ');
      DBMS_OUTPUT.PUT_LINE('ERROR: of Note 977512.1 for 11gR2 or note 1509653.1 for 12c .');
      RAISE_APPLICATION_ERROR(-20034, 'Stopping script - see previous message ...');
    END IF;
  END;

  -- Check if DST_SECONDARY_TT_VERSION is zero
  BEGIN
    BEGIN
      EXECUTE IMMEDIATE 'SELECT SUBSTR(property_value, 1, 3) 
                         FROM database_properties 
                         WHERE property_name = ''DST_SECONDARY_TT_VERSION''' 
      INTO V_CHECKNUM1;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: DST_PRIMARY_TT_VERSION FROM DATABASE_PROPERTIES gives no rows.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Do an manual update and checks as documented in ');
      DBMS_OUTPUT.PUT_LINE('ERROR: Note 977512.1 for 11gR2 or Note 1509653.1 for 12c.');
      RAISE_APPLICATION_ERROR(-20040, 'Stopping script - see previous message ...');
    END;
    IF V_CHECKNUM1 = '0' THEN
      NULL;
    ELSE
      DBMS_OUTPUT.PUT_LINE('ERROR: Current DST_SECONDARY_TT_VERSION is '|| TO_CHAR(V_CHECKNUM1) || ' !');
      DBMS_OUTPUT.PUT_LINE('ERROR: DST_SECONDARY_TT_VERSION in DATABASE_PROPERTIES need to be 0 ');
      DBMS_OUTPUT.PUT_LINE('ERROR: before this script can be run. ');
      DBMS_OUTPUT.PUT_LINE('ERROR: Do the checks as documented in point 3 ');
      DBMS_OUTPUT.PUT_LINE('ERROR: of note 977512.1 for 11gR2 or note 1509653.1 for 12c .');
      RAISE_APPLICATION_ERROR(-20041, 'Stopping script - see previous message ...');
    END IF;
  END;

  -- Get current TZ version seen in v$timezone_file
  -- Check that DST_PRIMARY_TT_VERSION value matches VERSION of V$TIMEZONE_FILE
  -- If not then someone messed with the *.dat files (renamed them or made symbolic links)
  BEGIN
    BEGIN
      EXECUTE IMMEDIATE 'SELECT version FROM v$timezone_file' INTO V_OLDDBTZV ;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: VERSION FROM V$TIMEZONE_FILE gives no rows.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Do an manual update and checks as documented in ');
      DBMS_OUTPUT.PUT_LINE('ERROR: Note 977512.1 for 11gR2 or Note 1509653.1 for 12c.');
      RAISE_APPLICATION_ERROR(-20050, 'Stopping script - see previous message ...');
    END;
    BEGIN
      EXECUTE IMMEDIATE 'SELECT SUBSTR(property_value, 1, 3)
                         FROM database_properties
                         WHERE property_name = ''DST_PRIMARY_TT_VERSION''' 
      INTO V_CHECKNUM1;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: DST_PRIMARY_TT_VERSION FROM DATABASE_PROPERTIES gives no rows.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Do an manual update and checks as documented in ');
      DBMS_OUTPUT.PUT_LINE('ERROR: Note 977512.1 for 11gR2 or Note 1509653.1 for 12c.');
      RAISE_APPLICATION_ERROR(-20051, 'Stopping script - see previous message ...');
    END;
    IF V_OLDDBTZV = V_CHECKNUM1 THEN
      DBMS_OUTPUT.PUT_LINE('INFO: Database RDBMS DST version is DSTv'|| TO_CHAR(V_OLDDBTZV) || ' .');
    ELSE
      DBMS_OUTPUT.PUT_LINE('ERROR: Current Server RDBMS DST version cannot be determined.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Do an manual update and checks as documented in ');
      DBMS_OUTPUT.PUT_LINE('ERROR: Note 977512.1 for 11gR2 or Note 1509653.1 for 12c.');
      RAISE_APPLICATION_ERROR(-20052, 'Stopping script - see previous message ...');
    END IF;
  END;

  -- REGISTRY$DATABASE cleanup of previous versions of this script
  -- Set TZ_VERSION_UPGRADE column to null if it exists
  BEGIN
    EXECUTE IMMEDIATE 'UPDATE registry$database SET tz_version_upgrade = NULL';
    COMMIT;
  EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE = -904 THEN -- REGISTRY$DATABASE exists but no TZ_VERSION_UPGRADE
      NULL;
    END IF;
    IF SQLCODE = -942 THEN -- no REGISTRY$DATABASE table
      NULL;
    END IF;
  END;
  -- Set TZ_VERSION column to current DST version
  BEGIN
    EXECUTE IMMEDIATE 'UPDATE registry$database SET tz_version = :1' USING V_OLDDBTZV;
   COMMIT;	
  EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE = -904 THEN -- REGISTRY$DATABASE exists but no TZ_VERSION
      NULL;
    END IF;
    IF SQLCODE = -942 THEN -- no REGISTRY$DATABASE table
      NULL;
    END IF;
  END;
  -- Drop table used by this script
  BEGIN
    EXECUTE IMMEDIATE 'DROP TABLE upg_tzv PURGE';
  EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE = -942 THEN -- ignore error if no UPG_TZV table
      NULL;
    END IF;
  END;  

  -- Version dependent checks for known bugs
  -- V_CHECKNUM2 is used to count issues found
  V_CHECKNUM2 := TO_NUMBER('0');
  --  11.2.0.1 only bugs
  IF V_DBVERSION IN ('11.2.0.1') THEN
    -- Check if case insensitive table or column names exist
    -- They give ORA-00904: invalid identifier
    -- or ORA-01747: invalid user.table.column, table.column, or column specification.
    -- Fixed in 11.2.0.2
    BEGIN
      EXECUTE IMMEDIATE 'SELECT COUNT(*)
                         FROM dba_tab_columns
                         WHERE data_type LIKE ''TIMESTAMP% WITH TIME ZONE'' AND
                               (UPPER(table_name) != table_name OR UPPER(column_name) != column_name)'
      INTO V_CHECKNUM1;
      IF V_CHECKNUM1 = TO_NUMBER('0') THEN
        NULL;
      ELSE
        DBMS_OUTPUT.PUT_LINE('ERROR: Case insensitive table or column names exist.');
        DBMS_OUTPUT.PUT_LINE('ERROR: ORA-00904 or ORA-01747 will be seen duing DBMS_DST.');
        DBMS_OUTPUT.PUT_LINE('ERROR: See known issues section of Note 977512.1 .');
        V_CHECKNUM2 := V_CHECKNUM2 + TO_NUMBER('1');
      END IF;
    END;
  END IF;
  -- no 11.2.0.2 only bugs exist
  -- 11.2.0.1, 11.2.0.2, 11.2.0.3 only bugs
  IF V_DBVERSION IN ('11.2.0.1', '11.2.0.2', '11.2.0.3') THEN
    -- Check if TIMESTAMP WITH TIME ZONE data type as part of an object subtype exist
    -- They give ORA-00907: missing right parenthesis
    -- Bug 13833939 - ora-0907 when preparing for dst upgrade.
    -- Fixed in 11.2.0.4 and 12c
    BEGIN
      EXECUTE IMMEDIATE 'SELECT COUNT(*)
                         FROM dba_tstz_tab_cols
                         WHERE INSTR(qualified_col_name,''TREAT'', 1, 1) > 0'
      INTO V_CHECKNUM1;
      IF V_CHECKNUM1 = TO_NUMBER('0') THEN
        NULL;
      ELSE
        DBMS_OUTPUT.PUT_LINE('ERROR: TSTZ data type as part of an object subtype exist.');
        DBMS_OUTPUT.PUT_LINE('ERROR: ORA-00907 will be seen during DBMS_DST.');
        DBMS_OUTPUT.PUT_LINE('ERROR: See known issues section of Note 977512.1 ');
        DBMS_OUTPUT.PUT_LINE('ERROR: for bug 13833939 .');
        V_CHECKNUM2 := V_CHECKNUM2 + TO_NUMBER('1');
      END IF;
    END;
    -- Check if there are virtual TSTZ columns
    -- They give ORA-54017: UPDATE operation disallowed on virtual columns
    -- Bug 13436809: ORA-54017 UPDATE OPERATION DISALLOWED ON VIRTUAL COLUMNS ERROR RUNNING DBMS_DST
    -- Fixed in 11.2.0.4 and 12c
    BEGIN
      EXECUTE IMMEDIATE 'SELECT COUNT(*) 
                         FROM dba_tab_cols c, dba_objects o 
                         WHERE c.data_type LIKE ''%WITH TIME ZONE'' AND
                               c.virtual_column =''YES'' AND
                               o.object_type = ''TABLE'' AND 
                               c.owner = o.owner AND 
                               c.table_name = o.object_name'
      INTO V_CHECKNUM1;
      IF V_CHECKNUM1 = TO_NUMBER('0') THEN
        NULL;
      ELSE
        DBMS_OUTPUT.PUT_LINE('ERROR: Virtual TSTZ columns exist.');
        DBMS_OUTPUT.PUT_LINE('ERROR: ORA-54017 will be seen during DBMS_DST.');
        DBMS_OUTPUT.PUT_LINE('ERROR: See known issues section of Note 977512.1 ');
        DBMS_OUTPUT.PUT_LINE('ERROR: for bug 13436809 .');
        V_CHECKNUM2 := V_CHECKNUM2 + TO_NUMBER('1');
      END IF;
    END;
  END IF;
  -- Bugs not fixed before 12.2.0.1
  -- Check if there are unused TSTZ columns
  -- They give ORA-00904: "T"."SYS_C00001_-random number here-": invalid identifier
  -- Bug 14732853 - DBMS_DST DOES NOT HANDLE UNUSED TIMESTAMP WITH TIME ZONE COLUMNS
  -- [fixed as part of Bug 23288675 in 12.2.0.1]
  IF V_DBVERSION in ('11.2.0.1', '11.2.0.2', '11.2.0.3', '11.2.0.4', '11.2.0.5',
                     '12.1.0.1', '12.1.0.2') THEN
    BEGIN
      EXECUTE IMMEDIATE 'SELECT COUNT(*) 
                         FROM dba_tab_cols c, dba_unused_col_tabs o 
                         WHERE c.data_type LIKE ''%WITH TIME ZONE'' AND
                               c.owner = o.owner AND 
                               c.table_name = o.table_name AND
                               c.hidden_column = ''YES'''
      INTO V_CHECKNUM1;
      IF V_CHECKNUM1 = TO_NUMBER('0')THEN
        NULL;
      ELSE
        DBMS_OUTPUT.PUT_LINE('ERROR: Unused TSTZ columns exist.');
        DBMS_OUTPUT.PUT_LINE('ERROR: ORA-00904 will be seen during DBMS_DST.');
        DBMS_OUTPUT.PUT_LINE('ERROR: See the known issues section of  ');
        DBMS_OUTPUT.PUT_LINE('ERROR: Note 977512.1 for 11gR2 or Note 1509653.1 for 12c .');
        DBMS_OUTPUT.PUT_LINE('ERROR: for bug 14732853 .');
        V_CHECKNUM2 := V_CHECKNUM2 + TO_NUMBER('1');
      END IF;
    END;
  END IF;
  -- Error out if one of above problems is detected
  BEGIN
    IF V_CHECKNUM2 != TO_NUMBER('0') THEN
      RAISE_APPLICATION_ERROR(-20060, 'Stopping script - see previous message ...');
    ELSE
      DBMS_OUTPUT.PUT_LINE('INFO: No known issues detected.');
    END IF;
  END;
  -- create table for script
  BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE upg_tzv(new_tz_version NUMBER, ispdb VARCHAR2(3 CHAR))';
  END;
  -- insert row to indicate PDB or not
  BEGIN
    EXECUTE IMMEDIATE 'INSERT INTO upg_tzv(new_tz_version, ispdb) VALUES (NULL, :1)' USING V_ISPDB;
    COMMIT;
  END;
  -- End block
END;
/

SET TERMOUT OFF

-- Purging dba_recyclebin
PURGE dba_recyclebin;

-- Alter session to avoid issue in note 1407273.1
ALTER SESSION SET "_simple_view_merging" = TRUE;

SET TERMOUT ON
SET FEEDBACK OFF

-- Say what we do next
EXEC DBMS_OUTPUT.PUT_LINE('INFO: Now detecting new RDBMS DST version.' );

-- Now find new DST value
DECLARE
  V_NEWDBTZV      NUMBER;
  V_CHECKNUM1     NUMBER;
  V_CHECKVAR1     VARCHAR2(10 CHAR);
  V_ERRCODE       NUMBER;
  V_ERRMSG        VARCHAR2(140 CHAR);
  V_NUMFAIL       NUMBER;
  NO_NEW_TIMEZONE EXCEPTION;
  PRAGMA EXCEPTION_INIT(NO_NEW_TIMEZONE, -56921);
  INVALID_TIMEZONE_FILE EXCEPTION;
  PRAGMA EXCEPTION_INIT(INVALID_TIMEZONE_FILE, -30094);
  PREPWINDOW_FAIL EXCEPTION;
  PRAGMA EXCEPTION_INIT(PREPWINDOW_FAIL, -56922);
BEGIN
  -- Using DBMS_DST.BEGIN_PREPARE to find highest installed DST version
  -- by doing DBMS_DST.BEGIN_PREPARE FROM 199 to 1 .
  -- It will ORA-30094: failed to find the time zone data file if no DST patch is found
  -- in that case loop further .
  -- DBMS_DST.BEGIN_PREPARE will not error out if a newer than the current DST value
  -- is detected.
  -- A lower or equal than current TZ value gives ORA-56921: invalid time zone version,
  -- in that case stop.
  FOR I IN reverse 1..199
  LOOP
    BEGIN
      V_NEWDBTZV := I;
      DBMS_DST.BEGIN_PREPARE(I);
      EXIT;
    EXCEPTION
    WHEN INVALID_TIMEZONE_FILE THEN
      NULL;
    WHEN NO_NEW_TIMEZONE THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: No newer RDBMS DST patch has been detected.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Check if a newer RDBMS DST patch is actually installed.');
      EXECUTE IMMEDIATE 'DROP TABLE upg_tzv PURGE';
      RAISE_APPLICATION_ERROR(-20070, 'Stopping script - see previous message ...');
    WHEN PREPWINDOW_FAIL THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: ORA-56922: Starting a prepare window failed.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Most likely the shared pool is unable to allocate additional');
      DBMS_OUTPUT.PUT_LINE('ERROR: storage during the execution of the DBMS_DST.BEGIN_PREPARE package.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Flush the shared pool or bounced the database to free up the SGA ');
      DBMS_OUTPUT.PUT_LINE('ERROR: and then run utltz_upg_check.sql again.');
      EXECUTE IMMEDIATE 'DROP TABLE upg_tzv PURGE';
      RAISE_APPLICATION_ERROR(-20071, 'Stopping script - see previous message ...');
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: something went wrong during DBMS_DST.BEGIN_PREPARE');
      EXECUTE IMMEDIATE 'DROP TABLE upg_tzv PURGE';
      V_ERRCODE := SQLCODE;
      V_ERRMSG  := SUBSTR(SQLERRM,1,140);
      DBMS_OUTPUT.PUT_LINE('Error code ' || V_ERRCODE || ': ' || V_ERRMSG);
      RAISE_APPLICATION_ERROR(-20072, 'Stopping script - see previous message ...');
    END;
  END LOOP;
  -- Here we have if all went well a V_Newdbtzv value with the highest new TZ file found
  -- But it means also a DBMS_DST.BEGIN_PREPARE is already started
  -- So that is not needed in the following steps
  BEGIN
    DBMS_OUTPUT.PUT_LINE('INFO: Newest RDBMS DST version detected is DSTv'|| TO_CHAR(V_NEWDBTZV) || ' .' );
  END;
  -- Check if DST_UPGRADE_STATE is PREPARE
  BEGIN
    EXECUTE IMMEDIATE 'SELECT SUBSTR(property_value, 1, 10) 
                       FROM database_properties 
                       WHERE property_name = ''DST_UPGRADE_STATE''' 
    INTO V_CHECKVAR1;
    IF V_CHECKVAR1 = TO_CHAR('PREPARE') THEN
      NULL;
    ELSE
      DBMS_OUTPUT.PUT_LINE('ERROR: Current DST_UPGRADE_STATE is '|| V_CHECKVAR1 || ' !');
      DBMS_OUTPUT.PUT_LINE('ERROR: DST_UPGRADE_STATE in DATABASE_PROPERTIES needs to be PREPARE');
      DBMS_OUTPUT.PUT_LINE('ERROR: after a DBMS_DST.BEGIN_PREPARE.');
      DBMS_OUTPUT.PUT_LINE('ERROR: See Note 977512.1 for 11gR2 or Note 1509653.1 for 12c .');
      RAISE_APPLICATION_ERROR(-20080, 'Stopping script - see previous message ...');
    END IF;
  END;
  -- Update UPG_TZV with V_Newdbtzv time zone information
  BEGIN
    EXECUTE IMMEDIATE 'UPDATE upg_tzv SET new_tz_version = :1' USING V_NEWDBTZV;
    COMMIT;	
  END;
  -- End block
END;
/

-- Say what we do next
EXEC DBMS_OUTPUT.PUT_LINE('INFO: Next step is checking all TSTZ data.');
EXEC DBMS_OUTPUT.PUT_LINE('INFO: It might take a while before any further output is seen ...');

-- Start check on data
SET TERMOUT OFF

-- Clean up used objects
TRUNCATE TABLE SYS.DST$TRIGGER_TABLE;
TRUNCATE TABLE SYS.DST$AFFECTED_TABLES;
TRUNCATE TABLE SYS.DST$ERROR_TABLE;

SET TERMOUT ON

-- Need catch here for ORA-01882: timezone region not found -> if seen run the
-- Fix1882.sql script found in Note 414590.1 using the server home SQL*Plus and then retry
-- If this happens, DBMS_DST.END_PREPARE need be called before exiting
DECLARE
  V_ISPDB          VARCHAR2(3 CHAR);
  V_NEWDBTZV       NUMBER;
  V_CHECKNUM1      NUMBER;
  V_CHECKVAR1      VARCHAR2(10 CHAR);
  V_ERRCODE        NUMBER;
  V_ERRMSG         VARCHAR2(140 CHAR);
  V_NUMFAIL        NUMBER;
  INVALID_TIMEZONE EXCEPTION;
  PRAGMA EXCEPTION_INIT(INVALID_TIMEZONE, -1882);
BEGIN
  BEGIN
    DBMS_DST.FIND_AFFECTED_TABLES (AFFECTED_TABLES => 'SYS.DST$AFFECTED_TABLES', 
                                   LOG_ERRORS => TRUE, 
                                   LOG_ERRORS_TABLE => 'SYS.DST$ERROR_TABLE');
  EXCEPTION
  WHEN INVALID_TIMEZONE THEN
    DBMS_OUTPUT.PUT_LINE('ERROR: ORA-01882 was detected during DBMS_DST.FIND_AFFECTED_TABLES.');
    DBMS_OUTPUT.PUT_LINE('ERROR: Make sure to run utltz_upg_check.sql using the database home SQL*Plus.');
    DBMS_OUTPUT.PUT_LINE('ERROR: If this error is seen using the database home SQL*Plus');
    DBMS_OUTPUT.PUT_LINE('ERROR: then run the Fix1882.sql script found in Note 414590.1 ');
    DBMS_OUTPUT.PUT_LINE('ERROR: using the server home SQL*Plus.');
    DBMS_OUTPUT.PUT_LINE('ERROR: And then run utltz_upg_check.sql again.');
    DBMS_OUTPUT.PUT_LINE('ERROR: If this error persists, log an SR.');
    EXECUTE IMMEDIATE 'DROP TABLE upg_tzv PURGE';
    DBMS_DST.END_PREPARE;
    RAISE_APPLICATION_ERROR(-20090, 'Stopping script - see previous message ...');
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('ERROR: Something went wrong during DBMS_DST.FIND_AFFECTED_TABLES.');
    EXECUTE IMMEDIATE 'DROP TABLE upg_tzv PURGE';
    DBMS_DST.END_PREPARE;
    V_ERRCODE := SQLCODE;
    V_ERRMSG  := SUBSTR(SQLERRM, 1, 140);
    DBMS_OUTPUT.PUT_LINE('Error code ' || V_ERRCODE || ': ' || V_ERRMSG);
    RAISE_APPLICATION_ERROR(-20091, 'Stopping script - see previous message ...');
  END;
  -- If this gives count(*) > 0 then issue warning
  BEGIN
    EXECUTE IMMEDIATE 'SELECT COUNT(*) 
                       FROM sys.dst$error_table 
                       WHERE error_number IN (''1878'',''1883'')' 
    INTO V_CHECKNUM1 ;
    IF V_CHECKNUM1 != TO_NUMBER('0') THEN
      DBMS_OUTPUT.PUT_LINE('WARNING: Some TSTZ data that needs adjusting is detected');
      DBMS_OUTPUT.PUT_LINE('WARNING: during DBMS_DST.FIND_AFFECTED_TABLES.');
      DBMS_OUTPUT.PUT_LINE('WARNING: This is error_on_overlap_time and error_on_nonexisting_time data.');
      DBMS_OUTPUT.PUT_LINE('WARNING: For more information see ');
      DBMS_OUTPUT.PUT_LINE('WARNING: Note 977512.1 for 11gR2 or Note 1509653.1 for 12c .');
      DBMS_OUTPUT.PUT_LINE('WARNING: This is a message in case you want to check this data manually.' );
      DBMS_OUTPUT.PUT_LINE('WARNING: The exact rows are in SYS.DST$ERROR_TABLE' );
      DBMS_OUTPUT.PUT_LINE('WARNING: The utltz_upg_apply.sql script will adjust this data automatically.' );
      DBMS_OUTPUT.PUT_LINE('WARNING: It will not stop the DST upgrade.' );
    END IF;
  END;
  -- If this gives count(*) > 0 then issue warning
  BEGIN
    EXECUTE IMMEDIATE 'SELECT COUNT(*) 
                       FROM sys.dst$error_table 
                       WHERE error_number IN (''1882'')' 
    INTO V_CHECKNUM1;
    IF V_CHECKNUM1 != TO_NUMBER('0') THEN
      DBMS_OUTPUT.PUT_LINE('WARNING: Some TSTZ data that needs correcting is detected');
      DBMS_OUTPUT.PUT_LINE('WARNING: during DBMS_DST.FIND_AFFECTED_TABLES.');
      DBMS_OUTPUT.PUT_LINE('WARNING: This is 1882 type data.');
      DBMS_OUTPUT.PUT_LINE('WARNING: For more information see ');
      DBMS_OUTPUT.PUT_LINE('WARNING: Note 977512.1 for 11gR2 or Note 1509653.1 for 12c.');
      DBMS_OUTPUT.PUT_LINE('WARNING: This is a message in case you want to check this data manually.' );
      DBMS_OUTPUT.PUT_LINE('WARNING: The exact rows are in SYS.DST$ERROR_TABLE' );
      DBMS_OUTPUT.PUT_LINE('WARNING: The utltz_upg_apply.sql script will adjust this data automatically.' );
      DBMS_OUTPUT.PUT_LINE('WARNING: It will not stop the DST upgrade.' );
    END IF;
  END;
  -- If this gives count(*) > 0 then error - go manual
  BEGIN
    EXECUTE IMMEDIATE 'SELECT COUNT(*)
                       FROM sys.dst$error_table
                       WHERE error_number NOT IN (''1878'',''1883'',''1882'')'
    INTO V_CHECKNUM1;
    IF V_CHECKNUM1 != TO_NUMBER('0') THEN
      DBMS_OUTPUT.PUT_LINE('ERROR: Some data that cannot be handled automatically ');
      DBMS_OUTPUT.PUT_LINE('ERROR: was detected during FIND_AFFECTED_TABLES.');
      DBMS_OUTPUT.PUT_LINE('ERROR: Do a manual DST update and checks as documented in ');
      DBMS_OUTPUT.PUT_LINE('ERROR: note 977512.1 for 11gR2 or note 1509653.1 for 12c .');
      EXECUTE IMMEDIATE 'DROP TABLE upg_tzv PURGE';	  
      DBMS_DST.END_PREPARE;
      RAISE_APPLICATION_ERROR(-20092, 'Stopping script - see previous message ...');
    END IF;
  END;

  -- End the prepare window
  DBMS_DST.END_PREPARE;

  -- Check if DST_UPGRADE_STATE is NONE
  BEGIN
    EXECUTE IMMEDIATE 'SELECT SUBSTR(property_value, 1, 10)
                       FROM database_properties
                       WHERE property_name = ''DST_UPGRADE_STATE''' 
    INTO V_CHECKVAR1;
    IF V_CHECKVAR1 = TO_CHAR('NONE') THEN
      NULL;
    ELSE
      DBMS_OUTPUT.PUT_LINE('ERROR: Current DST_UPGRADE_STATE is '|| V_CHECKVAR1 || ' !');
      DBMS_OUTPUT.PUT_LINE('ERROR: DST_UPGRADE_STATE in DATABASE_PROPERTIES need to be NONE ');
      DBMS_OUTPUT.PUT_LINE('ERROR: after a DBMS_DST.END_PREPARE.');
      DBMS_OUTPUT.PUT_LINE('ERROR: See note 977512.1 for 11gR2 or note 1509653.1 for 12c.');
      RAISE_APPLICATION_ERROR(-20100, 'Stopping script - see previous message ...');
    END IF;
  END;

  -- End message
  BEGIN
      DBMS_OUTPUT.PUT_LINE('INFO: A newer RDBMS DST version than the one currently used is found.');
      DBMS_OUTPUT.PUT_LINE('INFO: Note that NO DST update was yet done.');
      DBMS_OUTPUT.PUT_LINE('INFO: Now run utltz_upg_apply.sql to do the actual RDBMS DST update.' );
      DBMS_OUTPUT.PUT_LINE('INFO: Note that the utltz_upg_apply.sql script will ' );
      DBMS_OUTPUT.PUT_LINE('INFO: restart the database 2 times WITHOUT any confirmation or prompt.' );
  END;

  -- Warning message
  BEGIN
    EXECUTE IMMEDIATE 'SELECT ispdb FROM upg_tzv' INTO V_ISPDB;
    IF V_ISPDB = 'YES' THEN
      -- For PDB, warn that PDB can only be opened in one single instance
      BEGIN
        EXECUTE IMMEDIATE 'SELECT COUNT(*)
                           FROM gv$pdbs
                           WHERE name = (SELECT SYS_CONTEXT(''USERENV'',''CON_NAME'') FROM dual) AND
                                 open_mode != ''MOUNTED'''
        INTO V_CHECKNUM1;
        IF V_CHECKNUM1 = 1 THEN
          NULL;
        ELSE
          DBMS_OUTPUT.PUT_LINE('WARNING: This PDB is not started in a single instance!');
          DBMS_OUTPUT.PUT_LINE('WARNING: Start this PDB in one single instance only');
          DBMS_OUTPUT.PUT_LINE('WARNING: BEFORE running utltz_upg_apply.sql!');
          DBMS_OUTPUT.PUT_LINE('WARNING: This is REQUIRED!');
        END IF;
      END;
    ELSE
      -- For non-CDB and CDB$ROOT, check if DB is RAC, if so, warn to restart RAC DB in single instance
      BEGIN
        EXECUTE IMMEDIATE 'SELECT UPPER(value)
                           FROM v$system_parameter
                           WHERE UPPER(name)=''CLUSTER_DATABASE'''
        INTO V_CHECKVAR1;
        IF V_CHECKVAR1 = TO_CHAR('FALSE') THEN
          NULL;
        ELSE
          DBMS_OUTPUT.PUT_LINE('WARNING: This RAC database is not started in single instance mode.');
          DBMS_OUTPUT.PUT_LINE('WARNING: Set cluster_database = false and start as single instance');
          DBMS_OUTPUT.PUT_LINE('WARNING: BEFORE running utltz_upg_apply.sql!');
          DBMS_OUTPUT.PUT_LINE('WARNING: This is REQUIRED!');
        END IF;
      END;
    END IF;
  EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE = -942 THEN -- ignore error if no UPG_TZV table
      NULL;
    END IF;
  END;
END;
/

-- get time elapsed in minutes
EXEC :V_TIME := ROUND((DBMS_UTILITY.GET_TIME - :V_TIME)/100/60)

-- write little info to alert.
DECLARE
  V_NEWDBTZV NUMBER;
BEGIN
  EXECUTE IMMEDIATE 'SELECT new_tz_version FROM upg_tzv' INTO V_NEWDBTZV;
  DBMS_SYSTEM.KSDWRT(2, 'utltz_upg_check sucessfully found newer RDBMS DSTv' || V_NEWDBTZV ||
                        ' and took '|| :V_TIME ||' minutes to run.');
  -- End block
END;
/

whenever SQLERROR CONTINUE
SET FEEDBACK ON

-- End of utltz_upg_check.sql

@?/rdbms/admin/sqlsessend.sql

OHA YOOOO