Automated Compilation of Invalid Database Objects in Oracle Multitenant Architecture

Detailed Description:

The compile_invalid_objects.sh script is designed to automate the identification and compilation of invalid objects across pluggable databases (PDBs) within an Oracle multitenant database environment. Invalid objects—such as packages, procedures, functions, triggers, views, types, and synonyms—can arise due to changes in underlying objects, dependencies, or after migrations and patching. This script provides a robust and repeatable mechanism to recompile these objects to ensure schema consistency and application functionality.

Key Features:

  • Instance and PDB Aware: Accepts input parameters for target database instance, PDB, and schema name to provide scoped compilation.
  • Schema-Specific Compilation: Can focus on a specific schema or compile across all schemas when no schema is specified.
  • Read-Write Mode Check: Verifies that the database is in READ WRITE mode before proceeding, ensuring changes can be applied.
  • Session Container Switching: Iterates through all PDBs in READ WRITE mode and alters session container context for cross-PDB compatibility.
  • Selective Object Types: Targets only compilable object types such as PACKAGE, PACKAGE BODY, TRIGGER, VIEW, PROCEDURE, FUNCTION, TYPE, and TYPE BODY.
  • Indicator File Mechanism: Uses a .ind file to prevent concurrent execution of the same job for a given instance.
  • Logging: Logs are maintained in a dedicated directory structure for auditing and troubleshooting purposes.
  • Safe Execution: Compilation commands are echoed for visibility; execution lines are commented (–EXECUTE IMMEDIATE v_sql;) for dry-run by default, and can be enabled as needed.
  • Error Handling: Captures and logs SQL execution failures without halting the entire script.

Usage Syntax:

 

compile_invalid_objects.sh -i <INSTANCE_NAME> -p <PDB_NAME> -o <SCHEMA_NAME>

 

Example:

 

./compile_invalid_objects.sh -i DEVDB -p SALES_PDB -o HR

 

Script:

###############################################################################

# File Name   : compile_invalid_objects.sh

# Author      : Vimal Raju

# Date        : 14/08/2025

# Description : Compile invalids objects

#

###############################################################################

#############################################################

#

# Display usage infommation

#

usage () {

echo ” ”

echo ” Compile the invalids objects ”

echo ”       -h Display this message”

echo ”       -i Specify the target database instance name ”

echo ”       -p Specify the target database PDB name ”

echo ”       -o Specify the target database schema name ”

echo ”     Example : compile_invalid_objects.sh -i DEV -p TEST -o SCOTT ”

exit 1

}

exitError1 () {

case ${DBA_TRACE} in

Y|y)  set -x ;;

esac

if [ -f ${INDFILE} ]; then

rm ${INDFILE}

fi

exit 1

}

validate() {

if [ ${#TARGET_INST} -eq 0 ]; then

echo “No Target instance specified!”

usage

fi

 

INDFILE=${IND_LOC}/${TARGET_INST}_compile_invalid_objects.ind

# To check if the indicator file is there

if [ -f ${INDFILE} ]; then

echo “Indicator file ${INDFILE} exists!”

exit 1

else

touch ${INDFILE}

fi

 

if [ -f ${LOG_LOC}/${TARGET_INST}_compile_invalid_objects_${DATE}.log ]; then

echo “”

else

touch ${LOG_LOC}/${TARGET_INST}_compile_invalid_objects_${DATE}.log

fi

db_status=$(sqlplus -s / as sysdba << EOF

set lines 170 pages 0 head off feed off termout off verify off

select open_mode from v\$database;

exit

EOF

)

if [ “${db_status}” != “READ WRITE” ]

then

echo ” ${TARGET_INST} is Down ”

exitError1

fi

}

compile_invalid_objects() {

$ORACLE_HOME/bin/sqlplus -s / as sysdba <<EOF

set pagesize 0 heading off feedback off lines 200

SET SERVEROUTPUT ON

DECLARE

CURSOR pdbs IS

SELECT name FROM v\$pdbs WHERE open_mode = ‘READ WRITE’;

v_sql CLOB;

BEGIN

FOR pdb_rec IN pdbs LOOP

DBMS_OUTPUT.PUT_LINE(‘———————————————–‘);

DBMS_OUTPUT.PUT_LINE(‘Compiling in PDB: ‘ || pdb_rec.name);

DBMS_OUTPUT.PUT_LINE(‘———————————————–‘);

EXECUTE IMMEDIATE ‘ALTER SESSION SET CONTAINER = ‘ || pdb_rec.name;

FOR obj IN (

SELECT owner, object_name, object_type

FROM dba_objects

WHERE object_type IN (‘PACKAGE’, ‘PACKAGE BODY’,’SYNONYM’,’TRIGGER’,’VIEW’,’PROCEDURE’,’FUNCTION’,’TYPE’,’TYPE BODY’)

AND status != ‘VALID’

AND (UPPER(owner) = UPPER(‘${SCHEMA_NAME}’) OR ‘${SCHEMA_NAME}’ IS NULL)

ORDER BY 1,3

) LOOP

BEGIN

IF obj.object_type = ‘PACKAGE BODY’ THEN

v_sql := ‘ALTER PACKAGE “‘ || obj.owner || ‘”.”‘ || obj.object_name || ‘” COMPILE BODY’;

ELSIF obj.object_type = ‘TYPE BODY’ THEN

v_sql := ‘ALTER TYPE “‘ || obj.owner || ‘”.”‘ || obj.object_name || ‘” COMPILE BODY’;

ELSE

v_sql := ‘ALTER ‘ || obj.object_type || ‘ “‘ || obj.owner || ‘”.”‘ || obj.object_name || ‘” COMPILE’;

END IF;

DBMS_OUTPUT.PUT_LINE(v_sql);

–EXECUTE IMMEDIATE v_sql;

EXCEPTION

WHEN OTHERS THEN

DBMS_OUTPUT.PUT_LINE(‘Failed: ‘ || v_sql);

END;

END LOOP;

END LOOP;

END;

/

EOF

}

TARGET_INST=

PDB_NAME=

SCHEMA_NAME=

MAIL_TO=globusdba@doyensys.com

DATE1=`date +”%d-%b-%Y %T”`

while getopts :hi:p:o: opt $*

do

case $opt in

  1. h) usage

;;

  1. i) TARGET_INST=${OPTARG}

echo TARGET_INST set to ${TARGET_INST}

;;

  1. p) PDB_NAME=${OPTARG}

echo PDB_NAME set to ${PDB_NAME}

;;

  1. o) SCHEMA_NAME=${OPTARG}

echo SCHEMA_NAME set to ${SCHEMA_NAME}

;;

*) echo “******************************************************************”

echo “${JOBNAME}: Invalid option found on command line: ${OPTARG}”

echo “******************************************************************”

usage

;;

esac

done

. ~/.bash_profile

. ~/oracle.env

DBA_HOME=/home/oracle

LOG_LOC=${DBA_HOME}/log

TMP_LOC=${DBA_HOME}/tmp

IND_LOC=${DBA_HOME}/ind

validate

compile_invalid_objects

if [ -f ${INDFILE} ]; then

rm -f ${INDFILE}

fi

Recent Posts