I am trying to create a report of INVALID objects in Oracle. The requirement is to print a custom message when no rows are returned (This is because the output will be redirected to an HTML report). I tried the following query:
(select count(*), owner,object_type,to_char( LAST_DDL_TIME, 'DD-MM-YYYY HH24:MI:SS' ) as last_ddl_time
from dba_objects
where status='INVALID' and trunc(last_ddl_time) = sysdate -1
group by owner,object_type , LAST_DDL_TIME order by object_type)
UNION
(select '** DDL Changes in the last 24 hours' text from dual);
Error am seeing:
ORA-00907: missing right parenthesis
While the individual queries work without an issue, it fails to execute when a UNION is introduced. How can I fix this?
Advertisement
Answer
It can’t work that way. If you’re using UNION
, SELECT
statements have to return the same number of columns which match in datatype.
This is an invalid procedure (created in my SYS
schema for simplicity; don’t do that yourself):
SQL> create or replace procedure p_test
2 is
3 begin
4 end;
5 /
Warning: Procedure created with compilation errors.
Query you’d run; notice NOT EXISTS
in the second query – it’ll prevent the message to be displayed if there are some invalid objects. Also, I modified date condition to “today” (subtracted 0
) as I can’t wait until tomorrow to post it.
SQL> select
2 count(*),
3 owner,
4 object_type,
5 to_char(LAST_DDL_TIME, 'DD-MM-YYYY HH24:MI:SS') as last_ddl_time
6 from dba_objects
7 where status = 'INVALID'
8 and trunc(last_ddl_time) = trunc(sysdate) - 0
9 group by owner,
10 object_type,
11 LAST_DDL_TIME
12 UNION
13 select
14 0,
15 null,
16 'DDL Changes in the last 24 hours',
17 to_char(sysdate, 'dd-mm-yyyy')
18 from dual
19 where not exists (select null
20 from dba_objects
21 where status = 'INVALID'
22 and trunc(last_ddl_time) = trunc(sysdate) - 0
23 )
24 order by object_type;
COUNT(*) OWNER OBJECT_TYPE LAST_DDL_TIME
---------- ---------- -------------------------------- -------------------
1 SYS PROCEDURE 04-04-2021 12:36:07
SQL>
If I drop the invalid procedure:
SQL> drop procedure p_test;
Procedure dropped.
SQL> select
2 count(*),
3 owner,
4 object_type,
5 to_char(LAST_DDL_TIME, 'DD-MM-YYYY HH24:MI:SS') as last_ddl_time
6 from dba_objects
7 where status = 'INVALID'
8 and trunc(last_ddl_time) = trunc(sysdate) - 0
9 group by owner,
10 object_type,
11 LAST_DDL_TIME
12 UNION
13 select
14 0,
15 null,
16 'DDL Changes in the last 24 hours',
17 to_char(sysdate, 'dd-mm-yyyy')
18 from dual
19 where not exists (select null
20 from dba_objects
21 where status = 'INVALID'
22 and trunc(last_ddl_time) = trunc(sysdate) - 0
23 )
24 order by object_type;
COUNT(*) OWNER OBJECT_TYPE LAST_DDL_TIME
---------- ---------- -------------------------------- -------------------
0 DDL Changes in the last 24 hours 04-04-2021
SQL>