-- ====================================================================================
-- Script Name : unused_objects_report.sql
-- Purpose : Identify unused or stale objects based on user-defined inactivity days
-- Author : ChatGPT for Raunak
-- ====================================================================================
SET ECHO OFF
SET LINESIZE 200
SET PAGESIZE 100
SET FEEDBACK OFF
SET VERIFY OFF
SET TRIMSPOOL ON
-- === Accept user input for age threshold ===
ACCEPT v_days NUMBER PROMPT 'Enter number of days to consider an object as UNUSED (e.g., 90): '
-- === Generate timestamped spool file ===
COLUMN spool_file_name NEW_VALUE spool_file
SELECT 'unused_objects_' || TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS') || '.lst' AS spool_file_name FROM dual;
SPOOL &spool_file
PROMPT ============================================================================
PROMPT Report: Objects Unused for at least &v_days days
PROMPT ============================================================================
COLUMN OWNER FORMAT A20
COLUMN OBJECT_NAME FORMAT A30
COLUMN OBJECT_TYPE FORMAT A20
COLUMN STATUS FORMAT A10
COLUMN CREATED FORMAT A20
COLUMN LAST_DDL_TIME FORMAT A20
COLUMN SEGMENT_SIZE_MB FORMAT 999,999.99
COLUMN LAST_ANALYZED FORMAT A20
SELECT
o.owner,
o.object_name,
o.object_type,
o.status,
o.created,
o.last_ddl_time,
ROUND(NVL(s.bytes, 0)/1024/1024, 2) AS segment_size_mb,
CASE
WHEN o.object_type = 'TABLE' THEN t.last_analyzed
ELSE NULL
END AS last_analyzed
FROM
dba_objects o
LEFT JOIN
dba_segments s
ON o.owner = s.owner
AND o.object_name = s.segment_name
AND s.segment_type = o.object_type
LEFT JOIN
dba_tab_statistics t
ON o.owner = t.owner
AND o.object_name = t.table_name
AND o.object_type = 'TABLE'
WHERE
o.owner NOT IN ('SYS', 'SYSTEM', 'SYSMAN', 'DBSNMP')
AND o.object_type IN ('TABLE', 'INDEX', 'VIEW', 'MATERIALIZED VIEW')
AND (
o.last_ddl_time < SYSDATE - &v_days
OR (o.object_type = 'TABLE' AND (t.last_analyzed IS NULL OR t.last_analyzed < SYSDATE - &v_days))
)
AND (s.bytes IS NULL OR s.bytes = 0 OR s.bytes < 1024*1024) -- < 1 MB
ORDER BY
o.owner, o.object_type, o.object_name;
PROMPT ============================================================================
PROMPT Done. Report saved to &spool_file
PROMPT ============================================================================
SPOOL OFF