JSON Support in Oracle Database 12c Release 1 (12.1.0.2)
This article describes the server side support for JSON in the database.
oracle 12cconfigurationintermediate
by OracleDba
16 views
This article describes the server side support for JSON in the database.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
DROP TABLE json_documents PURGE;
CREATE TABLE json_documents (
id RAW(16) NOT NULL,
data CLOB,
CONSTRAINT json_documents_pk PRIMARY KEY (id),
CONSTRAINT json_documents_json_chk CHECK (data IS JSON)
);
DROP TABLE json_documents PURGE;
CREATE TABLE json_documents (
id RAW(16) NOT NULL,
data CLOB,
CONSTRAINT json_documents_pk PRIMARY KEY (id),
CONSTRAINT json_documents_json CHECK (data IS JSON (STRICT))
);
INSERT INTO json_documents (id, data)
VALUES (SYS_GUID(),
'{
"FirstName" : "John",
"LastName" : "Doe",
"Job" : "Clerk",
"Address" : {
"Street" : "99 My Street",
"City" : "My City",
"Country" : "UK",
"Postcode" : "A12 34B"
},
"ContactDetails" : {
"Email" : "[email protected]",
"Phone" : "44 123 123456",
"Twitter" : "@johndoe"
},
"DateOfBirth" : "01-JAN-1980",
"Active" : true
}');
INSERT INTO json_documents (id, data)
VALUES (SYS_GUID(),
'{
"FirstName" : "Jayne",
"LastName" : "Doe",
"Job" : "Manager",
"Address" : {
"Street" : "100 My Street",
"City" : "My City",
"Country" : "UK",
"Postcode" : "A12 34B"
},
"ContactDetails" : {
"Email" : "[email protected]",
"Phone" : ""
},
"DateOfBirth" : "01-JAN-1982",
"Active" : false
}');
COMMIT;
UPDATE json_documents a
SET a.data = '{"FirstName" : "Invalid Document"'
WHERE a.data.FirstName = 'Jayne';
*
ERROR at line 1:
ORA-02290: check constraint (TEST.DOCUMENT_JSON) violated
SQL>
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Postcode FORMAT A10
COLUMN Email FORMAT A25
SELECT a.data.FirstName,
a.data.LastName,
a.data.Address.Postcode AS Postcode,
a.data.ContactDetails.Email AS Email
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.LastName;
FIRSTNAME LASTNAME POSTCODE EMAIL
--------------- --------------- ---------- -------------------------
Jayne Doe A12 34B [email protected]
John Doe A12 34B [email protected]
2 rows selected.
SQL>
SELECT a.data.Address.Postcode
FROM json_documents a;
ADDRESS
----------
A12 34B
A12 34B
2 rows selected.
SQL>
SELECT a.data.ContactDetails
FROM json_documents a;
CONTACTDETAILS
-----------------------------------------------------------------------------
{"Email":"[email protected]","Phone":"44 123 123456","Twitter":"@johndoe"}
{"Email":"[email protected]","Phone":""}
2 rows selected.
SQL>
DROP TABLE json_documents_no_constraint PURGE;
CREATE TABLE json_documents_no_constraint (
id RAW(16) NOT NULL,
data CLOB,
CONSTRAINT json_documents_nocon_pk PRIMARY KEY (id)
);
INSERT INTO json_documents_no_constraint VALUES (SYS_GUID(), '{"FirstName" : "John"}');
INSERT INTO json_documents_no_constraint VALUES (SYS_GUID(), 'John');
COMMIT;
-- JSON_VALUE using NULL ON ERROR returns NULL for non-JSON data.
SELECT JSON_VALUE(a.data, '$.FirstName') AS first_name
FROM json_documents_no_constraint a;
FIRST_NAME
---------------
John
2 rows selected.
SQL>
-- Only rows containing JSON are returned.
SELECT JSON_VALUE(a.data, '$.FirstName') AS first_name
FROM json_documents_no_constraint a
WHERE a.data IS JSON;
FIRST_NAME
---------------
John
1 row selected.
SQL>
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Email FORMAT A25
COLUMN Phone FORMAT A15
COLUMN Twitter FORMAT A10
SELECT a.data.FirstName,
a.data.LastName,
a.data.ContactDetails.Email AS Email,
a.data.ContactDetails.Phone AS Phone,
a.data.ContactDetails.Twitter AS Twitter
FROM json_documents a
WHERE a.data.ContactDetails.Phone IS NULL
AND a.data.ContactDetails.Twitter IS NULL;
FIRSTNAME LASTNAME EMAIL PHONE TWITTER
--------------- --------------- ------------------------- --------------- ----------
Jayne Doe [email protected]
1 row selected.
SQL>
-- Check for records where a Phone element is present, but has a null value.
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Email FORMAT A25
SELECT a.data.FirstName,
a.data.LastName,
a.data.ContactDetails.Email AS Email
FROM json_documents a
WHERE JSON_EXISTS(a.data.ContactDetails, '$.Phone' FALSE ON ERROR)
AND a.data.ContactDetails.Phone IS NULL;
FIRSTNAME LASTNAME EMAIL
--------------- --------------- -------------------------
Jayne Doe [email protected]
1 row selected.
SQL>
-- Check for records where Twitter element is missing.
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Email FORMAT A25
SELECT a.data.FirstName,
a.data.LastName,
a.data.ContactDetails.Email AS Email
FROM json_documents a
WHERE NOT JSON_EXISTS(a.data.ContactDetails, '$.Twitter' FALSE ON ERROR);
FIRSTNAME LASTNAME EMAIL
--------------- --------------- -------------------------
Jayne Doe [email protected]
1 row selected.
SQL>
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
SELECT JSON_VALUE(a.data, '$.FirstName') AS first_name,
JSON_VALUE(a.data, '$.LastName') AS last_name
FROM json_documents a
ORDER BY 1, 2;
FIRST_NAME LAST_NAME
--------------- ---------------
Jayne Doe
John Doe
2 rows selected.
SQL>
SELECT JSON_VALUE(a.data, '$.ContactDetails') AS contact_details
FROM json_documents a
ORDER BY 1;
CONTACT_DETAILS
----------------------------------------
2 rows selected.
SQL>
SELECT JSON_VALUE(a.data, '$.ContactDetails' ERROR ON ERROR) AS contact_details
FROM json_documents a
ORDER BY 1;
*
ERROR at line 2:
ORA-40456: JSON_VALUE evaluated to non-scalar value
SQL>
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Active FORMAT A10
SELECT a.data.FirstName,
a.data.LastName,
JSON_VALUE(a.data, '$.Active') AS Active,
JSON_VALUE(a.data, '$.Active' RETURNING NUMBER) AS ActiveNum
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.LastName;
FIRSTNAME LASTNAME ACTIVE ACTIVENUM
--------------- --------------- ---------- ----------
Jayne Doe false 0
John Doe true 1
2 rows selected.
SQL>
{ VARCHAR2 [ ( size [BYTE | CHAR] ) ]
| NUMBER [ ( precision [, scale] ) ]
| DATE
| TIMESTAMP
| TIMESTAMP WITH TIME ZONE
| SDO_GEOMETRY
}
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
SELECT JSON_VALUE(a.data, '$.FirstName' RETURNING VARCHAR2) AS first_name,
JSON_VALUE(a.data, '$.LastName' RETURNING VARCHAR2(50)) AS last_name
FROM json_documents a
ORDER BY 1, 2;
FIRST_NAME LAST_NAME
--------------- ---------------
Jayne Doe
John Doe
2 rows selected.
SQL>
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN contact_details FORMAT A40
SELECT a.data.FirstName,
a.data.LastName,
JSON_QUERY(a.data, '$.ContactDetails' WITH WRAPPER) AS contact_details
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.Last_name;
FIRSTNAME LASTNAME CONTACT_DETAILS
--------------- --------------- ----------------------------------------
Jayne Doe [{"Email":"[email protected]","Phone
":""}]
John Doe [{"Email":"[email protected]","Phone"
:"44 123 123456","Twitter":"@johndoe"}]
2 rows selected.
SQL>
VARCHAR2 [ ( size [BYTE | CHAR] ) ]
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN contact_details FORMAT A40
SELECT a.data.FirstName,
a.data.LastName,
JSON_QUERY(a.data, '$.ContactDetails' RETURNING VARCHAR2(1000) WITH WRAPPER) AS contact_details
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.Last_name;
FIRSTNAME LASTNAME CONTACT_DETAILS
--------------- --------------- ----------------------------------------
Jayne Doe [{"Email":"[email protected]","Phone
":""}]
John Doe [{"Email":"[email protected]","Phone"
:"44 123 123456","Twitter":"@johndoe"}]
2 rows selected.
SQL>
CREATE OR REPLACE VIEW json_documents_v AS
SELECT jt.first_name,
jt.last_name,
jt.job,
jt.addr_street,
jt.addr_city,
jt.addr_country,
jt.addr_postcode,
jt.email,
jt.phone,
jt.twitter,
TO_DATE(jt.dob, 'DD-MON-YYYY') AS dob,
jt.active
FROM json_documents,
JSON_TABLE(data, '$'
COLUMNS (first_name VARCHAR2(50 CHAR) PATH '$.FirstName',
last_name VARCHAR2(50 CHAR) PATH '$.LastName',
job VARCHAR2(10 CHAR) PATH '$.Job',
addr_street VARCHAR2(50 CHAR) PATH '$.Address.Street',
addr_city VARCHAR2(50 CHAR) PATH '$.Address.City',
addr_country VARCHAR2(50 CHAR) PATH '$.Address.Country',
addr_postcode VARCHAR2(50 CHAR) PATH '$.Address.Postcode',
email VARCHAR2(100 CHAR) PATH '$.ContactDetails.Email',
phone VARCHAR2(50 CHAR) PATH '$.ContactDetails.Phone',
twitter VARCHAR2(50 CHAR) PATH '$.ContactDetails.Twitter',
dob VARCHAR2(11 CHAR) PATH '$.DateOfBirth',
active VARCHAR2(5 CHAR) PATH '$.Active')) jt;
COLUMN first_name FORMAT A15
COLUMN last_name FORMAT A15
SELECT first_name, last_name, dob
FROM json_documents_v
ORDER BY first_name, last_name;
FIRST_NAME LAST_NAME DOB
--------------- --------------- --------------------
Jayne Doe 01-JAN-1982 00:00:00
John Doe 01-JAN-1980 00:00:00
2 rows selected.
SQL>
COLUMN first_name FORMAT A15
COLUMN last_name FORMAT A15
COLUMN contact_details FORMAT A40
SELECT jt.first_name,
jt.last_name,
jt.contact_details
FROM json_documents,
JSON_TABLE(data, '$'
COLUMNS (first_name VARCHAR2(50 CHAR) PATH '$.FirstName',
last_name VARCHAR2(50 CHAR) PATH '$.LastName',
contact_details VARCHAR2(4000 CHAR)
FORMAT JSON WITH WRAPPER PATH '$.ContactDetails')) jt;
FIRST_NAME LAST_NAME CONTACT_DETAILS
--------------- --------------- ----------------------------------------
John Doe [{"Email":"[email protected]","Phone"
:"44 123 123456","Twitter":"@johndoe"}]
Jayne Doe [{"Email":"[email protected]","Phone
":""}]
2 rows selected.
SQL>
COLUMN table_name FORMAT A15
COLUMN column_name FORMAT A15
SELECT table_name,
column_name,
format,
data_type
FROM user_json_columns;
TABLE_NAME COLUMN_NAME FORMAT DATA_TYPE
--------------- --------------- --------- -------------
JSON_DOCUMENTS DATA TEXT CLOB
1 row selected.
SQL>
CONN sys@pdb1 AS SYSDBA
CREATE OR REPLACE DIRECTORY order_entry_dir
AS '/u01/app/oracle/product/12.1.0.2/db_1/demo/schema/order_entry';
GRANT READ, WRITE ON DIRECTORY order_entry_dir TO test;
CREATE OR REPLACE DIRECTORY loader_output_dir AS '/tmp';
GRANT READ, WRITE ON DIRECTORY loader_output_dir TO test;
CONN test/test@pdb1
CREATE TABLE json_dump_file_contents (json_document CLOB)
ORGANIZATION EXTERNAL (TYPE ORACLE_LOADER DEFAULT DIRECTORY order_entry_dir
ACCESS PARAMETERS
(RECORDS DELIMITED BY 0x'0A'
DISABLE_DIRECTORY_LINK_CHECK
BADFILE loader_output_dir: 'JSONDumpFile.bad'
LOGFILE order_entry_dir: 'JSONDumpFile.log'
FIELDS (json_document CHAR(5000)))
LOCATION (order_entry_dir:'PurchaseOrders.dmp'))
PARALLEL
REJECT LIMIT UNLIMITED;
SELECT COUNT(*) FROM json_dump_file_contents;
COUNT(*)
----------
10000
1 row selected.
SQL>
TRUNCATE TABLE json_documents;
INSERT /*+ APPEND */ INTO json_documents
SELECT SYS_GUID(), json_document
FROM json_dump_file_contents
WHERE json_document IS JSON;
COMMIT;
SELECT value FROM v$diag_info WHERE name = 'Default Trace File';
VALUE
----------------------------------------------------------------
/u01/app/oracle/diag/rdbms/cdb1/cdb1/trace/cdb1_ora_2861.trc
1 row selected.
SQL>
ALTER SESSION SET EVENTS '10053 trace name context forever';
SELECT a.data.FirstName,
a.data.LastName
FROM json_documents a;
ALTER SESSION SET EVENTS '10053 trace name context off';
Final query after transformations:******* UNPARSED QUERY IS *******
SELECT JSON_QUERY("A"."DATA" FORMAT JSON , '$.FirstName' RETURNING VARCHAR2(4000)
ASIS WITHOUT ARRAY WRAPPER NULL ON ERROR) "FIRSTNAME",
JSON_QUERY("A"."DATA" FORMAT JSON , '$.LastName' RETURNING VARCHAR2(4000)
ASIS WITHOUT ARRAY WRAPPER NULL ON ERROR) "LASTNAME"
FROM "TEST"."JSON_DOCUMENTS" "A"
{ ERROR | NULL | DEFAULT literal } ON ERROR
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Active FORMAT A10
SELECT a.data.FirstName,
a.data.LastName,
JSON_VALUE(a.data, '$.Active'
ERROR ON ERROR
) AS Active,
JSON_VALUE(a.data, '$.Active' RETURNING NUMBER
ERROR ON ERROR
) AS ActiveNum
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.LastName;
COLUMN first_name FORMAT A15
COLUMN last_name FORMAT A15
COLUMN contact_details FORMAT A40
SELECT jt.first_name,
jt.last_name,
jt.contact_details
FROM json_documents,
JSON_TABLE(data, '$'
ERROR ON ERROR
COLUMNS (first_name VARCHAR2(50 CHAR) PATH '$.FirstName'
ERROR ON ERROR
,
last_name VARCHAR2(50 CHAR) PATH '$.LastName'
ERROR ON ERROR
,
contact_details VARCHAR2(4000 CHAR)
FORMAT JSON WITH WRAPPER PATH '$.ContactDetails'
ERROR ON ERROR
)) jt;123456789101112131415161718192021222324252627282930313233343536373839404142434445
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Postcode FORMAT A10
COLUMN Email FORMAT A25
SELECT a.data.FirstName,
a.data.LastName,
a.data.Address.Postcode AS Postcode,
a.data.ContactDetails.Email AS Email
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.LastName;
FIRSTNAME LASTNAME POSTCODE EMAIL
--------------- --------------- ---------- -------------------------
Jayne Doe A12 34B [email protected]
John Doe A12 34B [email protected]
2 rows selected.
SQL>
SELECT a.data.Address.Postcode
FROM json_documents a;
ADDRESS
----------
A12 34B
A12 34B
2 rows selected.
SQL>
SELECT a.data.ContactDetails
FROM json_documents a;
CONTACTDETAILS
-----------------------------------------------------------------------------
{"Email":"[email protected]","Phone":"44 123 123456","Twitter":"@johndoe"}
{"Email":"[email protected]","Phone":""}
2 rows selected.
SQL>1234567891011121314151617181920212223242526272829303132333435363738
DROP TABLE json_documents_no_constraint PURGE;
CREATE TABLE json_documents_no_constraint (
id RAW(16) NOT NULL,
data CLOB,
CONSTRAINT json_documents_nocon_pk PRIMARY KEY (id)
);
INSERT INTO json_documents_no_constraint VALUES (SYS_GUID(), '{"FirstName" : "John"}');
INSERT INTO json_documents_no_constraint VALUES (SYS_GUID(), 'John');
COMMIT;
-- JSON_VALUE using NULL ON ERROR returns NULL for non-JSON data.
SELECT JSON_VALUE(a.data, '$.FirstName') AS first_name
FROM json_documents_no_constraint a;
FIRST_NAME
---------------
John
2 rows selected.
SQL>
-- Only rows containing JSON are returned.
SELECT JSON_VALUE(a.data, '$.FirstName') AS first_name
FROM json_documents_no_constraint a
WHERE a.data IS JSON;
FIRST_NAME
---------------
John
1 row selected.
SQL>1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Email FORMAT A25
COLUMN Phone FORMAT A15
COLUMN Twitter FORMAT A10
SELECT a.data.FirstName,
a.data.LastName,
a.data.ContactDetails.Email AS Email,
a.data.ContactDetails.Phone AS Phone,
a.data.ContactDetails.Twitter AS Twitter
FROM json_documents a
WHERE a.data.ContactDetails.Phone IS NULL
AND a.data.ContactDetails.Twitter IS NULL;
FIRSTNAME LASTNAME EMAIL PHONE TWITTER
--------------- --------------- ------------------------- --------------- ----------
Jayne Doe [email protected]
1 row selected.
SQL>
-- Check for records where a Phone element is present, but has a null value.
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Email FORMAT A25
SELECT a.data.FirstName,
a.data.LastName,
a.data.ContactDetails.Email AS Email
FROM json_documents a
WHERE JSON_EXISTS(a.data.ContactDetails, '$.Phone' FALSE ON ERROR)
AND a.data.ContactDetails.Phone IS NULL;
FIRSTNAME LASTNAME EMAIL
--------------- --------------- -------------------------
Jayne Doe [email protected]
1 row selected.
SQL>
-- Check for records where Twitter element is missing.
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Email FORMAT A25
SELECT a.data.FirstName,
a.data.LastName,
a.data.ContactDetails.Email AS Email
FROM json_documents a
WHERE NOT JSON_EXISTS(a.data.ContactDetails, '$.Twitter' FALSE ON ERROR);
FIRSTNAME LASTNAME EMAIL
--------------- --------------- -------------------------
Jayne Doe [email protected]
1 row selected.
SQL>1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
SELECT JSON_VALUE(a.data, '$.FirstName') AS first_name,
JSON_VALUE(a.data, '$.LastName') AS last_name
FROM json_documents a
ORDER BY 1, 2;
FIRST_NAME LAST_NAME
--------------- ---------------
Jayne Doe
John Doe
2 rows selected.
SQL>
SELECT JSON_VALUE(a.data, '$.ContactDetails') AS contact_details
FROM json_documents a
ORDER BY 1;
CONTACT_DETAILS
----------------------------------------
2 rows selected.
SQL>
SELECT JSON_VALUE(a.data, '$.ContactDetails' ERROR ON ERROR) AS contact_details
FROM json_documents a
ORDER BY 1;
*
ERROR at line 2:
ORA-40456: JSON_VALUE evaluated to non-scalar value
SQL>
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Active FORMAT A10
SELECT a.data.FirstName,
a.data.LastName,
JSON_VALUE(a.data, '$.Active') AS Active,
JSON_VALUE(a.data, '$.Active' RETURNING NUMBER) AS ActiveNum
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.LastName;
FIRSTNAME LASTNAME ACTIVE ACTIVENUM
--------------- --------------- ---------- ----------
Jayne Doe false 0
John Doe true 1
2 rows selected.
SQL>
{ VARCHAR2 [ ( size [BYTE | CHAR] ) ]
| NUMBER [ ( precision [, scale] ) ]
| DATE
| TIMESTAMP
| TIMESTAMP WITH TIME ZONE
| SDO_GEOMETRY
}
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
SELECT JSON_VALUE(a.data, '$.FirstName' RETURNING VARCHAR2) AS first_name,
JSON_VALUE(a.data, '$.LastName' RETURNING VARCHAR2(50)) AS last_name
FROM json_documents a
ORDER BY 1, 2;
FIRST_NAME LAST_NAME
--------------- ---------------
Jayne Doe
John Doe
2 rows selected.
SQL>12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN contact_details FORMAT A40
SELECT a.data.FirstName,
a.data.LastName,
JSON_QUERY(a.data, '$.ContactDetails' WITH WRAPPER) AS contact_details
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.Last_name;
FIRSTNAME LASTNAME CONTACT_DETAILS
--------------- --------------- ----------------------------------------
Jayne Doe [{"Email":"[email protected]","Phone
":""}]
John Doe [{"Email":"[email protected]","Phone"
:"44 123 123456","Twitter":"@johndoe"}]
2 rows selected.
SQL>
VARCHAR2 [ ( size [BYTE | CHAR] ) ]
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN contact_details FORMAT A40
SELECT a.data.FirstName,
a.data.LastName,
JSON_QUERY(a.data, '$.ContactDetails' RETURNING VARCHAR2(1000) WITH WRAPPER) AS contact_details
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.Last_name;
FIRSTNAME LASTNAME CONTACT_DETAILS
--------------- --------------- ----------------------------------------
Jayne Doe [{"Email":"[email protected]","Phone
":""}]
John Doe [{"Email":"[email protected]","Phone"
:"44 123 123456","Twitter":"@johndoe"}]
2 rows selected.
SQL>1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
CREATE OR REPLACE VIEW json_documents_v AS
SELECT jt.first_name,
jt.last_name,
jt.job,
jt.addr_street,
jt.addr_city,
jt.addr_country,
jt.addr_postcode,
jt.email,
jt.phone,
jt.twitter,
TO_DATE(jt.dob, 'DD-MON-YYYY') AS dob,
jt.active
FROM json_documents,
JSON_TABLE(data, '$'
COLUMNS (first_name VARCHAR2(50 CHAR) PATH '$.FirstName',
last_name VARCHAR2(50 CHAR) PATH '$.LastName',
job VARCHAR2(10 CHAR) PATH '$.Job',
addr_street VARCHAR2(50 CHAR) PATH '$.Address.Street',
addr_city VARCHAR2(50 CHAR) PATH '$.Address.City',
addr_country VARCHAR2(50 CHAR) PATH '$.Address.Country',
addr_postcode VARCHAR2(50 CHAR) PATH '$.Address.Postcode',
email VARCHAR2(100 CHAR) PATH '$.ContactDetails.Email',
phone VARCHAR2(50 CHAR) PATH '$.ContactDetails.Phone',
twitter VARCHAR2(50 CHAR) PATH '$.ContactDetails.Twitter',
dob VARCHAR2(11 CHAR) PATH '$.DateOfBirth',
active VARCHAR2(5 CHAR) PATH '$.Active')) jt;
COLUMN first_name FORMAT A15
COLUMN last_name FORMAT A15
SELECT first_name, last_name, dob
FROM json_documents_v
ORDER BY first_name, last_name;
FIRST_NAME LAST_NAME DOB
--------------- --------------- --------------------
Jayne Doe 01-JAN-1982 00:00:00
John Doe 01-JAN-1980 00:00:00
2 rows selected.
SQL>
COLUMN first_name FORMAT A15
COLUMN last_name FORMAT A15
COLUMN contact_details FORMAT A40
SELECT jt.first_name,
jt.last_name,
jt.contact_details
FROM json_documents,
JSON_TABLE(data, '$'
COLUMNS (first_name VARCHAR2(50 CHAR) PATH '$.FirstName',
last_name VARCHAR2(50 CHAR) PATH '$.LastName',
contact_details VARCHAR2(4000 CHAR)
FORMAT JSON WITH WRAPPER PATH '$.ContactDetails')) jt;
FIRST_NAME LAST_NAME CONTACT_DETAILS
--------------- --------------- ----------------------------------------
John Doe [{"Email":"[email protected]","Phone"
:"44 123 123456","Twitter":"@johndoe"}]
Jayne Doe [{"Email":"[email protected]","Phone
":""}]
2 rows selected.
SQL>12345678910111213141516
COLUMN table_name FORMAT A15
COLUMN column_name FORMAT A15
SELECT table_name,
column_name,
format,
data_type
FROM user_json_columns;
TABLE_NAME COLUMN_NAME FORMAT DATA_TYPE
--------------- --------------- --------- -------------
JSON_DOCUMENTS DATA TEXT CLOB
1 row selected.
SQL>123456789101112131415161718192021222324252627282930313233343536373839404142
CONN sys@pdb1 AS SYSDBA
CREATE OR REPLACE DIRECTORY order_entry_dir
AS '/u01/app/oracle/product/12.1.0.2/db_1/demo/schema/order_entry';
GRANT READ, WRITE ON DIRECTORY order_entry_dir TO test;
CREATE OR REPLACE DIRECTORY loader_output_dir AS '/tmp';
GRANT READ, WRITE ON DIRECTORY loader_output_dir TO test;
CONN test/test@pdb1
CREATE TABLE json_dump_file_contents (json_document CLOB)
ORGANIZATION EXTERNAL (TYPE ORACLE_LOADER DEFAULT DIRECTORY order_entry_dir
ACCESS PARAMETERS
(RECORDS DELIMITED BY 0x'0A'
DISABLE_DIRECTORY_LINK_CHECK
BADFILE loader_output_dir: 'JSONDumpFile.bad'
LOGFILE order_entry_dir: 'JSONDumpFile.log'
FIELDS (json_document CHAR(5000)))
LOCATION (order_entry_dir:'PurchaseOrders.dmp'))
PARALLEL
REJECT LIMIT UNLIMITED;
SELECT COUNT(*) FROM json_dump_file_contents;
COUNT(*)
----------
10000
1 row selected.
SQL>
TRUNCATE TABLE json_documents;
INSERT /*+ APPEND */ INTO json_documents
SELECT SYS_GUID(), json_document
FROM json_dump_file_contents
WHERE json_document IS JSON;
COMMIT;123456789101112131415161718192021222324
SELECT value FROM v$diag_info WHERE name = 'Default Trace File';
VALUE
----------------------------------------------------------------
/u01/app/oracle/diag/rdbms/cdb1/cdb1/trace/cdb1_ora_2861.trc
1 row selected.
SQL>
ALTER SESSION SET EVENTS '10053 trace name context forever';
SELECT a.data.FirstName,
a.data.LastName
FROM json_documents a;
ALTER SESSION SET EVENTS '10053 trace name context off';
Final query after transformations:******* UNPARSED QUERY IS *******
SELECT JSON_QUERY("A"."DATA" FORMAT JSON , '$.FirstName' RETURNING VARCHAR2(4000)
ASIS WITHOUT ARRAY WRAPPER NULL ON ERROR) "FIRSTNAME",
JSON_QUERY("A"."DATA" FORMAT JSON , '$.LastName' RETURNING VARCHAR2(4000)
ASIS WITHOUT ARRAY WRAPPER NULL ON ERROR) "LASTNAME"
FROM "TEST"."JSON_DOCUMENTS" "A"1234567891011121314151617181920212223242526272829303132333435363738
{ ERROR | NULL | DEFAULT literal } ON ERROR
COLUMN FirstName FORMAT A15
COLUMN LastName FORMAT A15
COLUMN Active FORMAT A10
SELECT a.data.FirstName,
a.data.LastName,
JSON_VALUE(a.data, '$.Active'
ERROR ON ERROR
) AS Active,
JSON_VALUE(a.data, '$.Active' RETURNING NUMBER
ERROR ON ERROR
) AS ActiveNum
FROM json_documents a
ORDER BY a.data.FirstName,
a.data.LastName;
COLUMN first_name FORMAT A15
COLUMN last_name FORMAT A15
COLUMN contact_details FORMAT A40
SELECT jt.first_name,
jt.last_name,
jt.contact_details
FROM json_documents,
JSON_TABLE(data, '$'
ERROR ON ERROR
COLUMNS (first_name VARCHAR2(50 CHAR) PATH '$.FirstName'
ERROR ON ERROR
,
last_name VARCHAR2(50 CHAR) PATH '$.LastName'
ERROR ON ERROR
,
contact_details VARCHAR2(4000 CHAR)
FORMAT JSON WITH WRAPPER PATH '$.ContactDetails'
ERROR ON ERROR
)) jt;Please to add comments
No comments yet. Be the first to comment!