We've recently migrated our Oracle database from 10g to 12c (12.1.0.1.0). After considering an issue with some queries we deceided to further clean up the database and drop all unneeded objects.
Therefore I wrote a query that searches the database DDL for a certain text to show up, where a particular view or function is used.
SELECT
object_name, object_type, DBMS_METADATA.GET_DDL(object_type, object_name) as ddl_txt
FROM user_objects
WHERE object_type IN ( 'FUNCTION', 'VIEW', 'PROCEDURE', 'TRIGGER')
AND UPPER( DBMS_METADATA.GET_DDL(object_type, object_name) ) LIKE upper('%myFunction%')
This results in the following exception:
ORA-31600: invalid input value TYPE BODY for parameter OBJECT_TYPE in function GET_DDL
ORA-06512: at "SYS.DBMS_METADATA", line 5746
ORA-06512: at "SYS.DBMS_METADATA", line 8333
ORA-06512: at line 1
31600. 00000 - "invalid input value %s for parameter %s in function %s"
*Cause: A NULL or invalid value was supplied for the parameter.
*Action: Correct the input value and try the call again.
The exeption occures because we have 'Body Type' objects in our database and they do not provide a ddl with the DBMS_METADATA.GET_DDL()
. Running the query below brings out the exact same exception as from the initial query.
select dbms_metadata.get_ddl('TYPE BODY', 'myBodyStringType') from dual
So, I try to create an inner list to first reduce the list of all user object to the once I do really care by rewriting my query as followed:
select
lst.*,
DBMS_METADATA.GET_DDL(lst.object_type, lst.object_name) as ddl_txt
from (
SELECT
object_name, object_type
FROM user_objects
WHERE object_type IN ( 'FUNCTION', 'VIEW', 'PROCEDURE', 'TRIGGER')
) lst
where upper(DBMS_METADATA.GET_DDL(lst.object_type, lst.object_name)) like upper('%myFunction%')
The funny point is, that it brings out the same exception as shown above. I do not understand why that happens.
I expect Oracle to create the inner list first and consume the DBMS_METADATA.GET_DLL()
function only with the remaining values since same values will result in an exception. Why is Oracle doing something else here?
To solve that particular issue I have to add an ORDER BY
in the inner query what looks stupid to me. Why do I have to force Oracle to create an inner query first with using an ORDER BY
?
select
lst.*,
DBMS_METADATA.GET_DDL(lst.object_type, lst.object_name) as ddl_txt
from (
SELECT
object_name, object_type
FROM user_objects
WHERE object_type IN ( 'FUNCTION', 'VIEW', 'PROCEDURE', 'TRIGGER')
ORDER BY ROWNUM ASC
) lst
where upper(DBMS_METADATA.GET_DDL(lst.object_type, lst.object_name)) like upper('%myFunction%')
Thanks in advance for any explanation on why that happens? - I have in mind, that the later query was running without any issues on Oracle 10g.
(I'm worried to have the same behavior on other reports that do calculation which might be wrong because of that behavior!).
It's a bug. Oracle Support just confirmed to me that the exception occures due to a bug in Oracle Version 12.1.0.1 only.
There are two options to choose from:
1) update to Oracle Version 12.1.0.2 and the bug is fixed.
2) wait a couple weeks for a patch that Oracle is starting to work on soon. The patch will fix this issue in Oracle Version 12.1.0.1.
We did not decided which option we are taking, but I'm very confident that one or the other will work since Oracle Support did reproduce my problem.