Oracle Database 23ai: JSON Relational Duality Views


Oracle has just announced the release of Oracle Database 23ai on 2nd May 2024. You can find the announcement here. The new release is packed with 300+ new features. One of the features introduced is the JSON Relational Duality View. In this post we will look at the basics and try to understand this new feature.

What is JSON Relational Duality View?

The modern application development often use unstructured or semi-structured data, where data may be stored in the form of objects or documents or simply as key-value pairs. Different applications, coded in different languages and following different standards are integrated to each other. These integrated applications need a common standard to communicate and transmit data with each other. JSON is becoming the de-facto standard for storing and transmitting this data. It is a way of representing JavaScript objects in text-format. However, we can’t define relationships between the JSON documents themselves, the application must code relationships separately, as part of its logic. In particular, values that are part of one document cannot be shared by others. This leads to data duplication across different documents, which in turn can introduce inconsistencies when documents are updated.

On the other hand, when this data is stored in relational databases, the data is normalized and structured in a set of relational tables, which makes the data processing very efficient and versatile.

Jason Relational Duality View addresses this problem. It gives the best of both worlds. It exposes data stored in relational database tables as JSON documents. According to Oracle documentation: “The documents are materialized — generated on demand, not stored as such. Duality views give your data both a conceptual and an operational duality: it’s organized both relationally and hierarchically. You can base different duality views on data that’s stored in one or more of the same tables, providing different JSON hierarchies over the same, shared data.”

In short, what it means is that you can apply CRUD operations to the data using normal SQL, also we can do the same through any language having JSON support.

Let us understand with an example. We will be using the EMPLOYEES AND DEPARTMENTS tables available in the HR schema. You can refer to my blog here, to check how you can download and install Oracle Database 23ai Free on Oracle VM or how to run it on a Docker, here.

So, let’s begin:

Query the Departments Table:

SQL> SELECT * FROM hr.departments;

   DEPARTMENT_ID DEPARTMENT_NAME          MANAGER_ID    LOCATION_ID
________________ _____________________ _____________ ______________
              10 Administration                  200           1700
              20 Marketing                       201           1800
              30 Purchasing                      114           1700
              40 Human Resources                 203           2400
              50 Shipping                        121           1500
              60 IT                              103           1400
              70 Public Relations                204           2700
              80 Sales                           145           2500
              90 Executive                       100           1700
             100 Finance                         108           1700
             110 Accounting                      205           1700
             120 Treasury                                      1700
             130 Corporate Tax                                 1700
             140 Control And Credit                            1700
             150 Shareholder Services                          1700
             160 Benefits                                      1700
             170 Manufacturing                                 1700
             180 Construction                                  1700
             190 Contracting                                   1700
             200 Operations                                    1700
             210 IT Support                                    1700
             220 NOC                                           1700
             230 IT Helpdesk                                   1700
             240 Government Sales                              1700
             250 Retail Sales                                  1700
             260 Recruiting                                    1700
             270 Payroll                                       1700

27 rows selected.

Create JSON Relational Duality View

SQL>  CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW j_vw_dept AS
SELECT JSON {'_id' :d.department_id,
'deptName':d.department_name,
'MgrID' IS d.manager_id,
'LocID' IS d.location_id
}
FROM hr.departments d with insert update delete;

View J_VW_DEPT created.

Here, we are mapping the relational table.column_names (department_id, department_name, manager_id, location_id) to the column names ( _id, deptName, MgrID, LocID), that would be exposed in the JSON documents.

Also notice that we have used the keywords insert, update and delete, to control the DML operations that can be performed.

We can now select directly from the Duality view.

SQL> Select * from j_vw_dept;

DATA
________________________________________________________________________________________________________
{"_id":10,"deptName":"Administration","MgrID":200,"LocID":1700,"_metadata":{"etag":"4ACDE7AD7DC4A24A5F0789B0E2EE9318","asof":"000000000079792A"}}
{"_id":20,"deptName":"Marketing","MgrID":201,"LocID":1800,"_metadata":{"etag":"DEA26E4EBD429F44DE1C75ABA3161052","asof":"000000000079792A"}}
{"_id":30,"deptName":"Purchasing","MgrID":114,"LocID":1700,"_metadata":{"etag":"0FAF1EF54C7AAFAEE882C0B352FBDC2C","asof":"000000000079792A"}}
{"_id":40,"deptName":"Human Resources","MgrID":203,"LocID":2400,"_metadata":{"etag":"343638B3BBF361CB5519C192795722DF","asof":"000000000079792A"}}
{"_id":50,"deptName":"Shipping","MgrID":121,"LocID":1500,"_metadata":{"etag":"7DF15A35E039FC5764489667CCE149FA","asof":"000000000079792A"}}
{"_id":60,"deptName":"IT","MgrID":103,"LocID":1400,"_metadata":{"etag":"875AEDF41CEF357EFAFB594825156F8E","asof":"000000000079792A"}}
{"_id":70,"deptName":"Public Relations","MgrID":204,"LocID":2700,"_metadata":{"etag":"DD5ABEA07BB0EE2BC3765BCAECE0F772","asof":"000000000079792A"}}
{"_id":80,"deptName":"Sales","MgrID":145,"LocID":2500,"_metadata":{"etag":"D685D281008A858531056FAC0E616CFA","asof":"000000000079792A"}}
{"_id":90,"deptName":"Executive","MgrID":100,"LocID":1700,"_metadata":{"etag":"12BE6D5B993E9067A07C130234376DD2","asof":"000000000079792A"}}
{"_id":100,"deptName":"Finance","MgrID":108,"LocID":1700,"_metadata":{"etag":"4F362719FC5F6BC9F260EFAF6BE1D716","asof":"000000000079792A"}}
{"_id":110,"deptName":"Accounting","MgrID":205,"LocID":1700,"_metadata":{"etag":"E143B72DB16F4165E0C6D3F526CD5243","asof":"000000000079792A"}}
{"_id":120,"deptName":"Treasury","MgrID":null,"LocID":1700,"_metadata":{"etag":"F2C9EB92CD5BCFB9290AB3E8974E6946","asof":"000000000079792A"}}
{"_id":130,"deptName":"Corporate Tax","MgrID":null,"LocID":1700,"_metadata":{"etag":"30B97A90F35550A48AAFFE60C9094F9A","asof":"000000000079792A"}}
{"_id":140,"deptName":"Control And Credit","MgrID":null,"LocID":1700,"_metadata":{"etag":"32D60823AE4EA580F031696D5964BD75","asof":"000000000079792A"}}
{"_id":150,"deptName":"Shareholder Services","MgrID":null,"LocID":1700,"_metadata":{"etag":"11744E05CC5555ADEBC7B171AE7AEEF7","asof":"000000000079792A"}}
{"_id":160,"deptName":"Benefits","MgrID":null,"LocID":1700,"_metadata":{"etag":"38B28536E84D912098476D354B1AC5DD","asof":"000000000079792A"}}
{"_id":170,"deptName":"Manufacturing","MgrID":null,"LocID":1700,"_metadata":{"etag":"B6A10B4833645557AE66DA4F47F26014","asof":"000000000079792A"}}
{"_id":180,"deptName":"Construction","MgrID":null,"LocID":1700,"_metadata":{"etag":"69B6603CD9511D8A2BCDA2D8D24E3E4A","asof":"000000000079792A"}}
{"_id":190,"deptName":"Contracting","MgrID":null,"LocID":1700,"_metadata":{"etag":"1F37FD4A4BFDF13CA8F1098B7D92B853","asof":"000000000079792A"}}
{"_id":200,"deptName":"Operations","MgrID":null,"LocID":1700,"_metadata":{"etag":"089A323C36622469246A00CB665981EF","asof":"000000000079792A"}}
{"_id":210,"deptName":"IT Support","MgrID":null,"LocID":1700,"_metadata":{"etag":"8B327BD5EB68A49AEFA1C4A2DED7F536","asof":"000000000079792A"}}
{"_id":220,"deptName":"NOC","MgrID":null,"LocID":1700,"_metadata":{"etag":"74748B6DFEC3ED0D7DB09DE6D140DF54","asof":"000000000079792A"}}
{"_id":230,"deptName":"IT Helpdesk","MgrID":null,"LocID":1700,"_metadata":{"etag":"5B2BE2CE481208D55F27737550DFF5BA","asof":"000000000079792A"}}
{"_id":240,"deptName":"Government Sales","MgrID":null,"LocID":1700,"_metadata":{"etag":"F6F51B54396D4410576BEA7A2C4A3C43","asof":"000000000079792A"}}
{"_id":250,"deptName":"Retail Sales","MgrID":null,"LocID":1700,"_metadata":{"etag":"549BEA246B2DC4BD9593886634215416","asof":"000000000079792A"}}
{"_id":260,"deptName":"Recruiting","MgrID":null,"LocID":1700,"_metadata":{"etag":"EC3BEF0F5BC18DFB07BF6206D4F1405C","asof":"000000000079792A"}}
{"_id":270,"deptName":"Payroll","MgrID":null,"LocID":1700,"_metadata":{"etag":"F062792C3837E1AA66F6DA9F0B2AF9DD","asof":"000000000079792A"}}

27 rows selected.

Notice that we have got one row for each department.

Additionally, we also get the header metadata with etag and asof. This is to enable optimistic locking for web-applications. We shall discuss optimistic locking in another blog.

You can use the json_serialize function to make the output more readable.

SQL> Select json_serialize(data pretty) from j_vw_dept;

JSON_SERIALIZE(DATAPRETTY)

_______________________________________________________________________________________________________________________________________________________________________________________________________
{
"_id" : 10,
"_metadata" :
{
"etag" : "4ACDE7AD7DC4A24A5F0789B0E2EE9318",
"asof" : "0000000000797CCF"
},
"deptName" : "Administration",
"MgrID" : 200,
"LocID" : 1700
}
{
"_id" : 20,
"_metadata" :
{
"etag" : "DEA26E4EBD429F44DE1C75ABA3161052",
"asof" : "0000000000797CCF"
},
"deptName" : "Marketing",
"MgrID" : 201,
"LocID" : 1800
}
{
"_id" : 30,
"_metadata" :
{
"etag" : "0FAF1EF54C7AAFAEE882C0B352FBDC2C",
"asof" : "0000000000797CCF"
},
"deptName" : "Purchasing",
"MgrID" : 114,
"LocID" : 1700
}
{
"_id" : 40,
"_metadata" :
{
"etag" : "343638B3BBF361CB5519C192795722DF",
"asof" : "0000000000797CCF"
},
"deptName" : "Human Resources",
"MgrID" : 203,
"LocID" : 2400
}
{
"_id" : 50,
"_metadata" :
{
"etag" : "7DF15A35E039FC5764489667CCE149FA",
"asof" : "0000000000797CCF"
},
"deptName" : "Shipping",
"MgrID" : 121,
"LocID" : 1500
}
{
"_id" : 60,
"_metadata" :
{
"etag" : "875AEDF41CEF357EFAFB594825156F8E",
"asof" : "0000000000797CCF"
},
"deptName" : "IT",
"MgrID" : 103,
"LocID" : 1400
}
{
"_id" : 70,
"_metadata" :
{
"etag" : "DD5ABEA07BB0EE2BC3765BCAECE0F772",
"asof" : "0000000000797CCF"
},
"deptName" : "Public Relations",
"MgrID" : 204,
"LocID" : 2700
}
{
"_id" : 80,
"_metadata" :
{
"etag" : "D685D281008A858531056FAC0E616CFA",
"asof" : "0000000000797CCF"
},
"deptName" : "Sales",
"MgrID" : 145,
"LocID" : 2500
}
{
"_id" : 90,
"_metadata" :
{
"etag" : "12BE6D5B993E9067A07C130234376DD2",
"asof" : "0000000000797CCF"
},
"deptName" : "Executive",
"MgrID" : 100,
"LocID" : 1700
}
{
"_id" : 100,
"_metadata" :
{
"etag" : "4F362719FC5F6BC9F260EFAF6BE1D716",
"asof" : "0000000000797CCF"
},
"deptName" : "Finance",
"MgrID" : 108,
"LocID" : 1700
}
{
"_id" : 110,
"_metadata" :
{
"etag" : "E143B72DB16F4165E0C6D3F526CD5243",
"asof" : "0000000000797CCF"
},
"deptName" : "Accounting",
"MgrID" : 205,
"LocID" : 1700
}
{
"_id" : 120,
"_metadata" :
{
"etag" : "F2C9EB92CD5BCFB9290AB3E8974E6946",
"asof" : "0000000000797CCF"
},
"deptName" : "Treasury",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 130,
"_metadata" :
{
"etag" : "30B97A90F35550A48AAFFE60C9094F9A",
"asof" : "0000000000797CCF"
},
"deptName" : "Corporate Tax",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 140,
"_metadata" :
{
"etag" : "32D60823AE4EA580F031696D5964BD75",
"asof" : "0000000000797CCF"
},
"deptName" : "Control And Credit",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 150,
"_metadata" :
{
"etag" : "11744E05CC5555ADEBC7B171AE7AEEF7",
"asof" : "0000000000797CCF"
},
"deptName" : "Shareholder Services",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 160,
"_metadata" :
{
"etag" : "38B28536E84D912098476D354B1AC5DD",
"asof" : "0000000000797CCF"
},
"deptName" : "Benefits",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 170,
"_metadata" :
{
"etag" : "B6A10B4833645557AE66DA4F47F26014",
"asof" : "0000000000797CCF"
},
"deptName" : "Manufacturing",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 180,
"_metadata" :
{
"etag" : "69B6603CD9511D8A2BCDA2D8D24E3E4A",
"asof" : "0000000000797CCF"
},
"deptName" : "Construction",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 190,
"_metadata" :
{
"etag" : "1F37FD4A4BFDF13CA8F1098B7D92B853",
"asof" : "0000000000797CCF"
},
"deptName" : "Contracting",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 200,
"_metadata" :
{
"etag" : "089A323C36622469246A00CB665981EF",
"asof" : "0000000000797CCF"
},
"deptName" : "Operations",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 210,
"_metadata" :
{
"etag" : "8B327BD5EB68A49AEFA1C4A2DED7F536",
"asof" : "0000000000797CCF"
},
"deptName" : "IT Support",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 220,
"_metadata" :
{
"etag" : "74748B6DFEC3ED0D7DB09DE6D140DF54",
"asof" : "0000000000797CCF"
},
"deptName" : "NOC",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 230,
"_metadata" :
{
"etag" : "5B2BE2CE481208D55F27737550DFF5BA",
"asof" : "0000000000797CCF"
},
"deptName" : "IT Helpdesk",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 240,
"_metadata" :
{
"etag" : "F6F51B54396D4410576BEA7A2C4A3C43",
"asof" : "0000000000797CCF"
},
"deptName" : "Government Sales",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 250,
"_metadata" :
{
"etag" : "549BEA246B2DC4BD9593886634215416",
"asof" : "0000000000797CCF"
},
"deptName" : "Retail Sales",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 260,
"_metadata" :
{
"etag" : "EC3BEF0F5BC18DFB07BF6206D4F1405C",
"asof" : "0000000000797CCF"
},
"deptName" : "Recruiting",
"MgrID" : null,
"LocID" : 1700
}
{
"_id" : 270,
"_metadata" :
{
"etag" : "F062792C3837E1AA66F6DA9F0B2AF9DD",
"asof" : "0000000000797CCF"
},
"deptName" : "Payroll",
"MgrID" : null,
"LocID" : 1700
}

27 rows selected.

Now let us take a step further and create a JSON Relational Duality View which de-normalizes the tables DEPARTMENTS and EMPLOYEES.

SQL> CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW j_vw_deptemp AS
SELECT JSON {'_id' IS d.department_id,
'deptName' IS d.department_name,
'MgrID' IS d.manager_id,
'LocID' IS d.location_id,
'employees' IS [ select json { 'empId' IS e.employee_id,
'empFirstName' IS e.first_name,
'empLastName' IS e.last_name,
'email' IS e.email,
'phone' IS e.phone_number,
'hireDate' IS e.hire_date,
'job' IS e.job_id,
'salary' IS e.salary,
'commission' IS e.commission_pct,
'managerId' IS e.manager_id}
from employees e with insert update delete
where d.department_id = e.department_id ] }
FROM hr.departments d with insert update delete;

View J_VW_DEPTEMP created.

We query the data. (**Showing only a part of the output below)

SQL> Select * from j_vw_deptemp;

{"_id":10,"deptName":"Administration","MgrID":200,"LocID":1700,"employees":[{"empId":200,"empFirstName":"Jennifer","empLastName":"Whalen","email":"JWHALEN","phone":"515.123.4444","hireDate":"2003-09-17T00:00:00","job":"AD_ASST","salary":4400,"commission":null,"managerId":101}],"_metadata":{"etag":"F114D57DC751F07705E084D389567441","asof":"00000000007983D6"}}{"_id":20,"deptName":"Marketing","MgrID":201,"LocID":1800,"employees":[{"empId":201,"empFirstName":"Michael","empLastName":"Hartstein","email":"MHARTSTE","phone":"515.123.5555","hireDate":"2004-02-17T00:00:00","job":"MK_MAN","salary":13000,"commission":null,"managerId":100},{"empId":202,"empFirstName":"Pat","empLastName":"Fay","email":"PFAY","phone":"603.123.6666","hireDate":"2005-08-17T00:00:00","job":"MK_REP","salary":6000,"commission":null,"managerId":201}],"_metadata":{"etag":"970A6BE884005790BC5388FC5A4EB012","asof":"00000000007983D6"}}
~~~~~~~~
{"_id":220,"deptName":"NOC","MgrID":null,"LocID":1700,"employees":[],"_metadata":{"etag":"E360D9CDB41EF0CCAB8D9982FB6661A4","asof":"00000000007983D6"}}
{"_id":230,"deptName":"IT Helpdesk","MgrID":null,"LocID":1700,"employees":[],"_metadata":{"etag":"426AD90EB6C85CCB4475090FC0089D6C","asof":"00000000007983D6"}}
{"_id":240,"deptName":"Government Sales","MgrID":null,"LocID":1700,"employees":[],"_metadata":{"etag":"4D784400653F14F96FB9DEAB0941349E","asof":"00000000007983D6"}}
{"_id":250,"deptName":"Retail Sales","MgrID":null,"LocID":1700,"employees":[],"_metadata":{"etag":"402D5702E8EEAFAB18323BD101ACA622","asof":"00000000007983D6"}}
{"_id":260,"deptName":"Recruiting","MgrID":null,"LocID":1700,"employees":[],"_metadata":{"etag":"D721FC0F101E49052DB3106F13BB431D","asof":"00000000007983D6"}}
{"_id":270,"deptName":"Payroll","MgrID":null,"LocID":1700,"employees":[],"_metadata":{"etag":"438802948433A88DF64BB2FB13FAFC33","asof":"00000000007983D6"}}
~~~~~~~~

** Note: There is a limitation of 4000 character for json_serialize function. I got the following error:

You can also select the JSON document for a specific department. Here, I am select the records from the duality view for DEPARTMENT_ID = 210. Notice that the array for employees is NULL, as DEPARTMENT_ID = 210 does not have any employees.

SQL> SELECT json_serialize(data pretty) from j_vw_deptemp j WHERE j.data."_id" = 210;

JSON_SERIALIZE(DATAPRETTY)

________________________________________________________________________________________________________
{
"_id" : 210,
"_metadata" :
{
"etag" : "BC5EB481B74D81A4BB100EC8AD371F92",
"asof" : "000000000079644C"
},
"deptName" : "IT Support",
"MgrID" : null,
"LocID" : 1700,
"employees" :
[
]
}

You can check the metadata of the viewusing DESC. I’m using SQLcl, so am using INFO. It contains only one column of data-type JSON.

SQL> INFO j_vw_deptemp
Columns
NAME DATA TYPE NULL DEFAULT COMMENTS
DATA JSON Yes

Details about the JSON-Relational Duality Views can be found in the following views:

  • USER_JSON_DUALITY_VIEWS
  • USER_JSON_DUALITY_VIEW_TABS
  • USER_JSON_DUALITY_VIEW_TAB_COLS
  • USER_JSON_DUALITY_VIEW_LINKS

Now let us perform some DML operations.

Update using JSON Relational Duality View

I will add an employee for DEPARTMENT_ID = 210 using the JSON Relational View.

SQL> UPDATE j_vw_deptemp jde
SET data = ('
{ "_id" : "210",
"deptName" :"IT Support",
"MgrID" : NULL,
"LocID" : "1700",
"employees" : [ { "empId" : 90000,
"empFirstName" : "Rishin",
"empLastName" : "Mitra",
"email" : "RMitra",
"phone" : "12345",
"hireDate" : "2002-06-07",
"job" : "IT_PROG",
"salary" : "12008",
"commission" : NULL,
"managerId" : NULL} ] }
')
WHERE jde.data."_id" = 210;

1 row updated.

If I now query the duality view, I shall see the employee.

I select the records from the duality view for DEPARTMENT_ID = 210. Notice that the array for employees is NULL, as DEPARTMENT_ID = 210 does not have any employees.

SQL> SELECT json_serialize(data pretty) from j_vw_deptemp j WHERE j.data."_id" = 210;

JSON_SERIALIZE(DATAPRETTY)

________________________________________________________________________________________________________
{
"_id" : 210,
"_metadata" :
{
"etag" : "BC5EB481B74D81A4BB100EC8AD371F92",
"asof" : "000000000079644C"
},
"deptName" : "IT Support",
"MgrID" : null,
"LocID" : 1700,
"employees" :
[
]
}

I can directly query the employees table.

SQL> SELECT * FROM employees where department_id = 210;

EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
______________ _____________ ____________ _________ _______________ ____________ __________ _________ _________________ _____________ ________________
90000 Rishin Mitra RMitra 12345 07-JUN-02 IT_PROG 12008 210

Insert using JSON Relational Duality View

Using this duality view, we can insert a new department and an employee for the department, as shown below:

SQL> INSERT INTO j_vw_deptemp jde (data)
VALUES('
{ "_id" : "300",
"deptName" :"JSON-INSERT",
"MgrID" : NULL,
"LocID" : "1700",
"employees" : [ { "empId" : 99999,
"empFirstName" : "Darryl",
"empLastName" : "G",
"email" : "DG",
"phone" : "67890",
"hireDate" : "2002-06-07",
"job" : "IT_PROG",
"salary" : "12008",
"commission" : NULL,
"managerId" : NULL} ] }
');

1 row inserted.

We can query the view.

SQL> SELECT json_serialize(data pretty) FROM j_vw_deptemp j WHERE j.data."_id" = 300;

JSON_SERIALIZE(DATAPRETTY)


________________________________________________________________________________________________________
{
"_id" : 300,
"_metadata" :
{
"etag" : "58BC105CBA0A642F552DCAD54A0BCC40",
"asof" : "0000000000796EC2"
},
"deptName" : "JSON-INSERT",
"MgrID" : null,
"LocID" : 1700,
"employees" :
[
{
"empId" : 99999,
"empFirstName" : "Darryl",
"empLastName" : "G",
"email" : "DG",
"phone" : "67890",
"hireDate" : "2002-06-07T00:00:00",
"job" : "IT_PROG",
"salary" : 12008,
"commission" : null,
"managerId" : null
}
]
}

We can also query the relational tables to confirm that the records have been inserted successfully.

SQL> SELECT * FROM departments WHERE department_id = 300 ;

DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID
________________ __________________ _____________ ______________
300 JSON-INSERT 1700

SQL> SELECT * FROM employees WHERE department_id = 300 ;

EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
______________ _____________ ____________ ________ _______________ ____________ __________ _________ _________________ _____________ ________________
99999 Darryl G DG 67890 07-JUN-02 IT_PROG 12008 300

Delete using JSON Relational Duality View

We can delete the data from the underlying relational tables if we delete a department from the duality view.

SQL> Delete From j_vw_deptemp j WHERE j.data."_id" = 300 ;

1 row deleted.

We query the data first from the view.

SQL> Select json_serialize(data pretty) from j_vw_deptemp j WHERE j.data."_id" = 300;

no rows selected

We query the relational tables to confirm.

SQL> Select * from departments where department_id = 300 ;

no rows selected
SQL> Select * from employees Where DEPARTMENT_ID = 300 ;

no rows selected

And there you go, we have learnt how we can create and JSON Relational Duality View and how we can perform DML operations on the underlying relational tables using a JSON.

In the next post, we will see some use-cases using JSON Relational Duality View.

References

Leave a comment