-- DROP TABLE json_documents PURGE;
CREATE TABLE json_documents (
id NUMBER,
data VARCHAR2(4000),
CONSTRAINT json_documents_is_json CHECK (data IS JSON)
);
TRUNCATE TABLE json_documents;
INSERT INTO json_documents (id, data)
SELECT rownum,
JSON_OBJECT(
'EMPNO' : empno,
'ENAME' : ename,
'JOB' : job
)
FROM emp;
COMMIT;
SET PAGESIZE 1000
COLUMN data FORMAT A50
SELECT * FROM json_documents;
ID DATA
---------- --------------------------------------------------
1 {"EMPNO":7369,"ENAME":"SMITH","JOB":"CLERK"}
2 {"EMPNO":7499,"ENAME":"ALLEN","JOB":"SALESMAN"}
3 {"EMPNO":7521,"ENAME":"WARD","JOB":"SALESMAN"}
4 {"EMPNO":7566,"ENAME":"JONES","JOB":"MANAGER"}
5 {"EMPNO":7654,"ENAME":"MARTIN","JOB":"SALESMAN"}
6 {"EMPNO":7698,"ENAME":"BLAKE","JOB":"MANAGER"}
7 {"EMPNO":7782,"ENAME":"CLARK","JOB":"MANAGER"}
8 {"EMPNO":7788,"ENAME":"SCOTT","JOB":"ANALYST"}
9 {"EMPNO":7839,"ENAME":"KING","JOB":"PRESIDENT"}
10 {"EMPNO":7844,"ENAME":"TURNER","JOB":"SALESMAN"}
11 {"EMPNO":7876,"ENAME":"ADAMS","JOB":"CLERK"}
12 {"EMPNO":7900,"ENAME":"JAMES","JOB":"CLERK"}
13 {"EMPNO":7902,"ENAME":"FORD","JOB":"ANALYST"}
14 {"EMPNO":7934,"ENAME":"MILLER","JOB":"CLERK"}
14 rows selected.
SQL>
CREATE TYPE T_EMP_ROW AS OBJECT (
EMPNO NUMBER(4),
ENAME VARCHAR2(10),
JOB VARCHAR2(9)
);
/
SELECT JSON_VALUE(data, '$'
RETURNING t_emp_row
) AS employee
FROM json_documents;
EMPLOYEE(EMPNO, ENAME, JOB)
--------------------------------------------------------------------------------
T_EMP_ROW(7369, 'SMITH', 'CLERK')
T_EMP_ROW(7499, 'ALLEN', 'SALESMAN')
T_EMP_ROW(7521, 'WARD', 'SALESMAN')
T_EMP_ROW(7566, 'JONES', 'MANAGER')
T_EMP_ROW(7654, 'MARTIN', 'SALESMAN')
T_EMP_ROW(7698, 'BLAKE', 'MANAGER')
T_EMP_ROW(7782, 'CLARK', 'MANAGER')
T_EMP_ROW(7788, 'SCOTT', 'ANALYST')
T_EMP_ROW(7839, 'KING', 'PRESIDENT')
T_EMP_ROW(7844, 'TURNER', 'SALESMAN')
T_EMP_ROW(7876, 'ADAMS', 'CLERK')
T_EMP_ROW(7900, 'JAMES', 'CLERK')
T_EMP_ROW(7902, 'FORD', 'ANALYST')
T_EMP_ROW(7934, 'MILLER', 'CLERK')
14 rows selected.
SQL>
TRUNCATE TABLE json_documents;
INSERT INTO json_documents (id, data)
VALUES (1, (
SELECT JSON_OBJECT('EMPLOYEES' :
JSON_ARRAYAGG (
JSON_OBJECT(
'EMPNO' : empno,
'ENAME' : ename,
'JOB' : job
)
)
)
FROM emp));
COMMIT;
SET PAGESIZE 1000
COLUMN data FORMAT A50
SELECT * FROM json_documents;
ID DATA
---------- --------------------------------------------------
1 {"EMPLOYEES":[{"EMPNO":7369,"ENAME":"SMITH","JOB":
"CLERK"},{"EMPNO":7499,"ENAME":"ALLEN","JOB":"SALE
SMAN"},{"EMPNO":7521,"ENAME":"WARD","JOB":"SALESMA
N"},{"EMPNO":7566,"ENAME":"JONES","JOB":"MANAGER"}
,{"EMPNO":7654,"ENAME":"MARTIN","JOB":"SALESMAN"},
{"EMPNO":7698,"ENAME":"BLAKE","JOB":"MANAGER"},{"E
MPNO":7782,"ENAME":"CLARK","JOB":"MANAGER"},{"EMPN
O":7788,"ENAME":"SCOTT","JOB":"ANALYST"},{"EMPNO":
7839,"ENAME":"KING","JOB":"PRESIDENT"},{"EMPNO":78
44,"ENAME":"TURNER","JOB":"SALESMAN"},{"EMPNO":787
6,"ENAME":"ADAMS","JOB":"CLERK"},{"EMPNO":7900,"EN
AME":"JAMES","JOB":"CLERK"},{"EMPNO":7902,"ENAME":
"FORD","JOB":"ANALYST"},{"EMPNO":7934,"ENAME":"MIL
LER","JOB":"CLERK"}]}
1 row selected.
SQL>
CREATE TYPE T_EMP_TAB AS TABLE OF T_EMP_ROW;
/
SELECT JSON_VALUE(data, '$.EMPLOYEES'
RETURNING t_emp_tab
) AS employees
FROM json_documents;
EMPLOYEES(EMPNO, ENAME, JOB)
--------------------------------------------------------------------------------
T_EMP_TAB(T_EMP_ROW(7369, 'SMITH', 'CLERK'), T_EMP_ROW(7499, 'ALLEN', 'SALESMAN'
), T_EMP_ROW(7521, 'WARD', 'SALESMAN'), T_EMP_ROW(7566, 'JONES', 'MANAGER'), T_E
MP_ROW(7654, 'MARTIN', 'SALESMAN'), T_EMP_ROW(7698, 'BLAKE', 'MANAGER'), T_EMP_R
OW(7782, 'CLARK', 'MANAGER'), T_EMP_ROW(7788, 'SCOTT', 'ANALYST'), T_EMP_ROW(783
9, 'KING', 'PRESIDENT'), T_EMP_ROW(7844, 'TURNER', 'SALESMAN'), T_EMP_ROW(7876,
'ADAMS', 'CLERK'), T_EMP_ROW(7900, 'JAMES', 'CLERK'), T_EMP_ROW(7902, 'FORD', 'A
NALYST'), T_EMP_ROW(7934, 'MILLER', 'CLERK'))
1 row selected.
SQL>
TRUNCATE TABLE json_documents;
INSERT INTO json_documents (id, data)
SELECT ROWNUM,
JSON_OBJECT (
'DEPTNO' : d.deptno,
'DNAME' : d.dname,
'EMPLOYEES' : (
SELECT JSON_ARRAYAGG (
JSON_OBJECT(
'EMPNO' : e.empno,
'ENAME' : e.ename,
'JOB' : e.job
)
)
FROM emp e
WHERE e.deptno = d.deptno
)
) AS department
FROM dept d;
COMMIT;
SET PAGESIZE 1000
COLUMN data FORMAT A50
SELECT * FROM json_documents;
ID DATA
---------- --------------------------------------------------
1 {"DEPTNO":10,"DNAME":"ACCOUNTING","EMPLOYEES":[{"E
MPNO":7782,"ENAME":"CLARK","JOB":"MANAGER"},{"EMPN
O":7839,"ENAME":"KING","JOB":"PRESIDENT"},{"EMPNO"
:7934,"ENAME":"MILLER","JOB":"CLERK"}]}
2 {"DEPTNO":20,"DNAME":"RESEARCH","EMPLOYEES":[{"EMP
NO":7369,"ENAME":"SMITH","JOB":"CLERK"},{"EMPNO":7
566,"ENAME":"JONES","JOB":"MANAGER"},{"EMPNO":7788
,"ENAME":"SCOTT","JOB":"ANALYST"},{"EMPNO":7876,"E
NAME":"ADAMS","JOB":"CLERK"},{"EMPNO":7902,"ENAME"
:"FORD","JOB":"ANALYST"}]}
3 {"DEPTNO":30,"DNAME":"SALES","EMPLOYEES":[{"EMPNO"
:7499,"ENAME":"ALLEN","JOB":"SALESMAN"},{"EMPNO":7
521,"ENAME":"WARD","JOB":"SALESMAN"},{"EMPNO":7654
,"ENAME":"MARTIN","JOB":"SALESMAN"},{"EMPNO":7698,
"ENAME":"BLAKE","JOB":"MANAGER"},{"EMPNO":7844,"EN
AME":"TURNER","JOB":"SALESMAN"},{"EMPNO":7900,"ENA
ME":"JAMES","JOB":"CLERK"}]}
4 {"DEPTNO":40,"DNAME":"OPERATIONS","EMPLOYEES":null
}
4 rows selected.
SQL>
CREATE TYPE T_DEPT_ROW AS OBJECT (
DEPTNO NUMBER(2),
DNAME VARCHAR2(14),
EMPLOYEES T_EMP_TAB
);
/
SELECT JSON_VALUE(data, '$'
RETURNING t_dept_row
) AS department
FROM json_documents;
DEPARTMENT(DEPTNO, DNAME, EMPLOYEES(EMPNO, ENAME, JOB))
--------------------------------------------------------------------------------
T_DEPT_ROW(10, 'ACCOUNTING', T_EMP_TAB(T_EMP_ROW(7782, 'CLARK', 'MANAGER'), T_EM
P_ROW(7839, 'KING', 'PRESIDENT'), T_EMP_ROW(7934, 'MILLER', 'CLERK')))
T_DEPT_ROW(20, 'RESEARCH', T_EMP_TAB(T_EMP_ROW(7369, 'SMITH', 'CLERK'), T_EMP_RO
W(7566, 'JONES', 'MANAGER'), T_EMP_ROW(7788, 'SCOTT', 'ANALYST'), T_EMP_ROW(7876
, 'ADAMS', 'CLERK'), T_EMP_ROW(7902, 'FORD', 'ANALYST')))
T_DEPT_ROW(30, 'SALES', T_EMP_TAB(T_EMP_ROW(7499, 'ALLEN', 'SALESMAN'), T_EMP_RO
W(7521, 'WARD', 'SALESMAN'), T_EMP_ROW(7654, 'MARTIN', 'SALESMAN'), T_EMP_ROW(76
98, 'BLAKE', 'MANAGER'), T_EMP_ROW(7844, 'TURNER', 'SALESMAN'), T_EMP_ROW(7900,
'JAMES', 'CLERK')))
T_DEPT_ROW(40, 'OPERATIONS', NULL)
4 rows selected.
SQL>