I need to query the patch status on Oracle databases. Since Oracle version 12c the view sys.REGISTRY$HISTORY was replaced by the view DBA_REGISTRY_SQLPATCH. On older versions like 11g the view dba_registry_sqlpatch does not exist. The following query creates errors on oracle versions < 12c because the view dba_registry_sqlpatch does not exist. I need to build a query that runs on all oracle database versions. I can not use PL/SQL. I think it should be solved with a case expression.
/* Query for version < 11g: */
SELECT MIN (diff) diff, MIN (zeile) zeile
FROM (SELECT TO_CHAR (TRUNC (SYSDATE - TRUNC (action_time)), '9999') DIFF,
'DIFF : '
|| TO_CHAR (TRUNC (SYSDATE - TRUNC (action_time)), '9999')
|| ' DAYS '
|| 'ACTION='
|| action
|| ' VERSION='
|| version
|| ' DATE='
|| TO_CHAR (action_time, 'yyyymmdd')
|| ' ID='
|| TO_CHAR (id, '09')
|| ' COMMENTS='
|| comments
|| ' PORT='
|| (SELECT DBMS_UTILITY.port_string
FROM DUAL)
ZEILE
FROM sys.REGISTRY$HISTORY
WHERE action_time = (SELECT MAX (action_time)
FROM sys.REGISTRY$HISTORY
WHERE action IN ('APPLY', 'ROLLBACK'))
UNION ALL
/*Query for version 12c: */
(SELECT TO_CHAR (TRUNC (SYSDATE - TRUNC (action_time)), '9999') DIFF,
'DIFF : '
|| TO_CHAR (TRUNC (SYSDATE - TRUNC (action_time)), '9999')
|| ' DAYS '
|| 'ACTION='
|| action
|| ' VERSION='
|| version
|| ' DATE='
|| TO_CHAR (action_time, 'yyyymmdd')
|| ' ID='
|| TO_CHAR (patch_id)
|| ' COMMENTS='
|| description
|| ' PORT='
|| (SELECT DBMS_UTILITY.port_string
FROM DUAL)
ZEILE
FROM dba_registry_sqlpatch
WHERE action_time = (SELECT MAX (action_time)
FROM dba_registry_sqlpatch
WHERE action IN ('APPLY', 'ROLLBACK')))
UNION ALL
/* Query for no patch installed: */
SELECT (SELECT TO_CHAR (TRUNC (SYSDATE - TRUNC (created)), '9999')
FROM v$database)
DIFF,
'DIFF : '
|| (SELECT TO_CHAR (TRUNC (SYSDATE - TRUNC (created)), '9999')
FROM v$database)
|| ' DAYS ACTION=N./A. VERSION='
|| (SELECT SUBSTR (version, 1, 8)
FROM v$instance)
|| ' DATE='
|| (SELECT TO_CHAR (created, 'yyyymmdd')
FROM v$database)
|| ' ID= 99 COMMENTS='
|| (SELECT SUBSTR (version, 1, 8)
FROM v$instance)
|| ' PORT='
|| (SELECT DBMS_UTILITY.port_string
FROM DUAL)
ZEILE
FROM DUAL)
WHERE ROWNUM = 1;
Example output on an Oracle 12c database patched 11 days ago: DIFF : 11 DAYS ACTION=APPLY VERSION=12.1.0.2 DATE=20160429 ID=22809813 COMMENTS=WINDOWS DB BUNDLE PATCH 12.1.0.2.160419(64bit):22809813 PORT=IBMPC/WIN_NT64-9.1.0