Serializing/marshalling package level user define record types to JSON Serializing/marshalling package level user define record types to JSON json json

Serializing/marshalling package level user define record types to JSON


JSON_OBJECT_T does not have a constructor that takes in a record type so you will need to explicitly define each of the keys/values to define the JSON. JDOM_T is not required for what you are attempting to do. Below is an example on how to convert your record types to JSON and back.

DECLARE    TYPE RT_Address IS RECORD    (        Line1    VARCHAR2 (100),        Line2    VARCHAR2 (100),        City     VARCHAR2 (100)    );    TYPE RT_Customer IS RECORD    (        FirstName    VARCHAR2 (100),        LastName     VARCHAR2 (100),        Address      RT_Address    );    l_customer1   rt_customer        := rt_customer ('John', 'Doe', rt_address ('123 Main Street', 'Apartment# 2A', 'London'));    l_customer2   rt_customer        := rt_customer ('Jane', 'Smith', rt_address ('456 Broken Dreams Blvd', NULL, 'Greenville'));    l_json        json_object_t;    l_record      rt_customer;    FUNCTION customer_record_to_json (P_Customer RT_Customer)        RETURN json_object_t    IS        l_address    json_object_t := json_object_t ();        l_customer   json_object_t := json_object_t ();    BEGIN        l_address.put ('Line1', p_customer.address.line1);        l_address.put ('Line2', p_customer.address.line2);        l_address.put ('City', p_customer.address.city);        l_customer.put ('FirstName', p_customer.firstname);        l_customer.put ('LastName', p_customer.lastname);        l_customer.put ('Address', l_address);        RETURN l_customer;    END;    FUNCTION customer_json_to_record (p_customer_json json_object_t)        RETURN rt_customer    IS        l_address_json   json_object_t := json_object_t ();        l_address        rt_address;        l_customer       rt_customer;    BEGIN        l_address_json := p_customer_json.get_object ('Address');        l_address.line1 := l_address_json.get_string ('Line1');        l_address.line2 := l_address_json.get_string ('Line2');        l_address.city := l_address_json.get_string ('City');        l_customer.firstname := p_customer_json.get_string ('FirstName');        l_customer.lastname := p_customer_json.get_string ('LastName');        l_customer.address := l_address;        RETURN l_customer;    END;BEGIN    l_json := customer_record_to_json (l_customer1);    DBMS_OUTPUT.put_line ('Customer 1 (JSON): ' || l_json.stringify);    l_record := customer_json_to_record (l_json);    DBMS_OUTPUT.put_line ('Customer 1 (Record) (FirstName): ' || l_record.firstname);    DBMS_OUTPUT.put_line ('Customer 1 (Record) (LastName): ' || l_record.lastname);    DBMS_OUTPUT.put_line ('Customer 1 (Record) (Line1): ' || l_record.address.line1);    DBMS_OUTPUT.put_line ('Customer 1 (Record) (Line2): ' || l_record.address.line2);    DBMS_OUTPUT.put_line ('Customer 1 (Record) (City): ' || l_record.address.city);    l_json := customer_record_to_json (l_customer2);    DBMS_OUTPUT.put_line ('Customer 2 (JSON): ' || l_json.stringify);    l_record := customer_json_to_record (l_json);    DBMS_OUTPUT.put_line ('Customer 2 (Record) (FirstName): ' || l_record.firstname);    DBMS_OUTPUT.put_line ('Customer 2 (Record) (LastName): ' || l_record.lastname);    DBMS_OUTPUT.put_line ('Customer 2 (Record) (Line1): ' || l_record.address.line1);    DBMS_OUTPUT.put_line ('Customer 2 (Record) (Line2): ' || l_record.address.line2);    DBMS_OUTPUT.put_line ('Customer 2 (Record) (City): ' || l_record.address.city);END;

Update

It is possible to just JSON_OBJECT(*) to create a JSON object, but the * expansion will not work with record types as you will get a ORA-40579: star expansion is not allowed.

If you do wish to use JSON_OBJECT to create the JSON instead of JSON_OBJECT_T, the types you are using will need to be predefined (not in the pl/sql block) and you will still need to define each field in the JSON structure. You will also need to define a table type of the RT_CUSTOMER type so that you can query from it.

CREATE TYPE RT_Address AS OBJECT (Line1 VARCHAR2 (100), Line2 VARCHAR2 (100), City VARCHAR2 (100));CREATE TYPE RT_Customer AS OBJECT(    FirstName VARCHAR2 (100),    LastName VARCHAR2 (100),    Address RT_Address);CREATE TYPE rt_customer_t AS TABLE OF rt_customer;SELECT json_object (           'firstname' VALUE firstname,           'lastname' VALUE lastname,           'address' VALUE               json_object ('line1' VALUE TREAT (address AS rt_address).line1,                            'line2' VALUE TREAT (address AS rt_address).line2,                            'city' VALUE TREAT (address AS rt_address).city)) as customer  FROM TABLE (           rt_customer_t (               RT_Customer ('John',                            'Doe',                            rt_address ('123 Main Street', 'Apartment# 2A', 'London')),               RT_Customer ('Jane',                            'Smith',                            rt_address ('456 Broken Dreams Blvd', NULL, 'Greenville'))));