1

Oracle DB version 12.2

I have the following data model with two tables:

SQL> desc TABLE_A
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 FILENAME                                           VARCHAR2(100 CHAR)
 REPORT_DATE                                        VARCHAR2(12 CHAR)
 DOMAINCODE                                         VARCHAR2(10 CHAR)
 LEGALENTITYCODE                                    VARCHAR2(10 CHAR)

SQL> desc TABLE_B
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 FILENAME                                           VARCHAR2(100 CHAR)
 NATIVEKEY                                          VARCHAR2(50 CHAR)
 MASTERKEY                                          VARCHAR2(50 CHAR)
 ENDDATE                                            VARCHAR2(12 CHAR)

SQL>

So, I got this basic join query to get the results I want

SELECT 
       a.REPORT_DATE,
       a.DOMAINCODE,
       a.LEGALENTITYCODE,
       b.nativekey,
       b.masterkey,
       b.enddate
  FROM    TABLE_A a
       INNER JOIN
          TABLE_B b
       ON (NVL (a.filename, 'XX') = NVL (b.filename, 'XX')) 
       where a.domaincode = '00001';

Which gives me :

enter image description here

My requirement is to print this data in the form of a JSON document like this:

{
"Date":"2020-03-31"
,"DomainCode":"00001"
,"LegalEntityCode":"00055"
,"Keys":[
{
"NativeKey":"129582692"
,"MasterKey":"329323111430011996"
,"EndDate":"9999-12-31"
}
,{
"NativeKey":"14735034"
,"MasterKey":"329390935000331576"
,"EndDate":"9999-12-31"
}
]
}

As you can see above, the hierarchy of the data appears only once in the document, at the beginning. I've been playing around with SQL/JSON functions on 12.2 , but I always got the hierarchy on each record. I found a workaround using APEX_JSON, which gives me the format required, but its performance is not very good, and I am generating a document with 10 million rows. I know I can generate this using standard SQL and escaping/printing each special character, but I don't want to do that.

Is there any way to generate this in a standard way with JSON funcions like JSON_ARRAY and/or JSON_OBJECT ?

Thank you all!

2 Answers 2

1

Did you try json_arrayagg?

SELECT json_object('Date'            VALUE report_date,
                   'DomainCode'      value domaincode,
                   'Legalentitycode' value legalentitycode, 
                   'Keys'            VALUE json_arrayagg(
                                           json_object(
                                             'NativeKey' value nativekey,
                                             'MasterKey' value masterkey,
                                             'EndDate'   value enddate)))
  FROM  table_a a
  join table_b using (filename)
  GROUP BY filename, report_date, domaincode, legalentitycode;

dbfiddle

Sign up to request clarification or add additional context in comments.

8 Comments

Hi. I tried that, but I got with a limitation on 12.2 ( ORA-40459:output value too large). It could return a CLOB but not a JSON_OBJECT. I believe they fix the limitation in 18c
@RobertoHernandez - if your requirement is to print it, does it matter that it's a CLOB?
@Ponder Stibbons: Well, with the CLOB I have the problem that when I tried to print it to the spool the JSON document ends corrupted, with lines broken when as soon as I reach 32k. I tried to use a function to break the clob and avoid the unexpected return carriages, and I did, but the performance is slower than APEX_JSON. So that it is why at the end I discarded the solution.
Ask Tom has a good article about limitations of JSON SQL in 12.2 asktom.oracle.com/pls/apex/…
Going off--topic, if not hijacking this answer; but maybe you should look at utl_file instead of spool + dbms_output? The file would be on the server not the client, but even if you have to move it later, might be simpler and faster. You should ask a separate question about that though if you need more info.
|
0

After dealing with the issue, I could not find any solution within my current version 12.2 without applying a specific patch

Following Metalink note: ORA-40478 or ORA-40459 running JSON Generation Functions (Doc ID 2354511.1)

Workaround in 12.2

  • First apply <Patch 27521093: MERGE REQUEST ON TOP OF 12.2.0.1.0 FOR BUGS 24693010 25481087>
  • Enable extended data types
  • Set the returning clause of the json functions to varchar2(32767) or CLOB

So, the query should look like

SQL> SELECT JSON_OBJECT (
KEY 'json_data' VALUE json_data returning varchar2(32767)
)
FROM huge_json_value;

Or

select JSON_OBJECT(
KEY 'objects' VALUE
(SELECT JSON_ARRAYAGG(
JSON_OBJECT(
KEY 'object_type' VALUE object_type,
KEY 'object_name' VALUE object_name
)
returning varchar2(32767))
FROM dba_objects where rownum < 100
)
returning CLOB)
from dual;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.