JSON-Relational Duality Views let you expose your relational tables as flexible JSON documents — and update them both ways — without any data duplication. Here’s a practical, step-by-step guide to creating them.
Why Create Duality Views?
- Developers get simple JSON documents for modern apps
- DBAs keep normalized, relational tables for consistency and analytics
- Both views work on the exact same underlying data
Simple Duality View Example (Department)
-- 1. Create the underlying relational table
CREATE TABLE dept_tab (
deptno NUMBER(2,0) PRIMARY KEY,
dname VARCHAR2(14),
code NUMBER(13,0),
state VARCHAR2(15),
country VARCHAR2(15)
);
-- 2. Create the Duality View
CREATE JSON RELATIONAL DUALITY VIEW dept_dv AS
SELECT JSON { '_id' : d.deptno,
'deptName' : d.dname,
'location' : { 'zipcode' : d.code,
'country' : d.country }
FROM dept_tab d
WITH UPDATE INSERT DELETE;
This view now supports clean JSON documents while the data stays normalized in the table.
More Complex Example: Orders with Nested Data
CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW orders_ov AS
SELECT JSON { '_id' : ord.order_id,
'orderTime' : ord.order_datetime,
'orderStatus' : ord.order_status,
'customerInfo' : (SELECT JSON { 'customerId' : cust.customer_id,
'customerName' : cust.full_name,
'customerEmail': cust.email_address }
FROM customers cust
WHERE cust.customer_id = ord.customer_id),
'orderItems' : (SELECT JSON_ARRAYAGG(
JSON { 'orderItemId' : oi.line_item_id,
'quantity' : oi.quantity,
'productInfo' : ...,
'shipmentInfo': ... }
)
FROM order_items oi
WHERE ord.order_id = oi.order_id)
}
FROM orders ord
WITH INSERT UPDATE DELETE;
Controlling Updatability
Use the WITH clause to control what operations are allowed:
WITH INSERT UPDATE DELETE— Fully updatable (default for root table)WITH NOINSERT NODELETE NOUPDATE— Read-only- You can override at column level:
WITH NOUPDATEorWITH UPDATE
Key Rules for Duality Views
- Every underlying table needs at least one identifying column (primary key, unique key, or identity column)
- Use nested subqueries for 1-to-N relationships → becomes a JSON array
- Use
UNNESTfor 1-to-1 relationships to merge into the same object - Supported column types include VARCHAR2, NUMBER, DATE, JSON, VECTOR, etc.
- Each duality view has a single
DATAcolumn of type JSON
Automatic Metadata Fields
Every document automatically includes:
{
"_metadata": {
"etag": "abc123...", -- for optimistic concurrency
"asof": 1234567890 -- system change number (SCN)
}
}
Best Practices
- Start with simple single-table views to learn the pattern
- Use meaningful field names in JSON (not just column names)
- Combine with AI Vector Search or Private Agent Factory for powerful AI apps
- Always test updates through both the document view and relational tables
Conclusion
Creating JSON-Relational Duality Views is straightforward with a simple SQL statement. You get the best of both worlds: document flexibility for modern apps and relational power for analytics and integrity — all on the same data.