I have a question on how things are handled in SQL vs PL/SQL for the same code.
If I define a few simple types like this:
CREATE OR REPLACE TYPE PARENT FORCE IS OBJECT
(
parent_name VARCHAR2(128)
) NOT FINAL;
/
CREATE OR REPLACE TYPE child FORCE UNDER PARENT
(
child_name VARCHAR2(128)
);
/
And then define a simple function to get the type name (the idea being that I can get the type name of an object that I pass in which could be parent or any number of inherited types):
CREATE OR REPLACE FUNCTION get_type_name(p_obj PARENT) RETURN VARCHAR2 IS
BEGIN
RETURN sys.anydata.convertobject(obj => p_obj).gettypename;
END get_type_name;
/
If I run it like this:
DECLARE
v_child child;
BEGIN
dbms_output.put_line(get_type_name(p_obj => v_child));
END;
I get the type name of '<my_schema>.CHILD'
Which is what I want.
If I run it like this:
SELECT get_type_name(p_obj => child(parent_name => 'parent'
,child_name => 'chld')) type_name
FROM dual;
Or with SQL in a pl/sql context
SELECT get_type_name(p_obj => child(parent_name => 'parent'
,child_name => 'chld')) type_name
into v_type_name
FROM dual;
I get '<my_shchema>.PARENT'.
My question is: Why do the pl/sql and sql engines handle it differently? And can I rely on the pl/sql implementation to do this in future releases of Oracle (i.e. this is expected behavior and not a "bug" that could be fixed later).
Thanks in advance! I've learned so much from this site.
Why do the pl/sql and sql engines handle it differently
They shouldn't and I'd recommend logging an SR.
I'd be inclined to use caution when looking at ANYDATA mixed with inheritance and the like, because I'm seeing things like this
SQL> select sys.anydata.convertobject(parent('x')) from dual;
ERROR:
ORA-22636: collection unpickling failed due to corrupt image
on first call in a session, which leads me to suspect there are some issues here. You're probably hitting some edge cases. You might be able to workaround some of this via IS OF "type" clauses when dealing in the SQL space.