SQL22 min readBy Priyanshu Pandey

SQL Masterclass: JSON & XML Processing in Oracle

Learn how to natively generate, parse, and query JSON and XML payloads directly within Oracle SQL without needing a middle-tier application.

Integration Guide · SQL Masterclass

JSON & XML: Native Parsing in Oracle SQL

Modern integrations communicate in JSON and XML. Don't offload the parsing to a middle-tier microservice. Learn how to generate, slice, and query unstructured payloads directly inside the database.

22 min read📅August 7, 2026✍️Priyanshu Pandey📚SQL Masterclass

The Shift to Unstructured Data

Historically, Oracle databases strictly stored highly normalized relational data. If an external system sent an invoice, it was processed by a Java or Python middleware layer, broken into pieces, and inserted into INVOICE_HEADER and INVOICE_DETAILS tables.

With the rise of REST APIs and document databases, Oracle adapted. Beginning in 12c, and perfected in 19c and 21c, Oracle can natively store, query, and generate JSON and XML. You can now store a raw API payload in a CLOB column, enforce that it is valid JSON, and query elements out of it seamlessly using SQL.

Working with JSON

Parsing JSON (JSON_TABLE)

Assume we have a table API_LOGS with a CLOB column payload containing:

{
  "order_id": 1001,
  "customer": "Alice",
  "items": [
    {"item_no": "A1", "qty": 2},
    {"item_no": "B2", "qty": 1}
  ]
}

If we want to query this like a relational table, we use JSON_TABLE. It maps JSON paths to SQL columns.

SQL
SELECT 
  j.order_id,
  j.customer,
  j.item_no,
  j.qty
FROM api_logs a,
JSON_TABLE(
  a.payload, '$' 
  COLUMNS (
    order_id NUMBER PATH '$.order_id',
    customer VARCHAR2(50) PATH '$.customer',
    NESTED PATH '$.items[*]' COLUMNS (
      item_no VARCHAR2(20) PATH '$.item_no',
      qty NUMBER PATH '$.qty'
    )
  )
) j;

The NESTED PATH command beautifully unnests the array, automatically performing a relational join between the header elements (order_id) and the array elements!

Generating JSON

Going the other direction, you can convert relational tables into complex, nested JSON objects using JSON_OBJECT and JSON_ARRAYAGG.

SQL
SELECT JSON_OBJECT(
  'department_id' VALUE d.dept,
  'department_name' VALUE d.dept_name,
  'employees' VALUE JSON_ARRAYAGG(
    JSON_OBJECT('id' VALUE e.emp_id, 'name' VALUE e.emp_name)
  )
) as json_payload
FROM dept_table d
JOIN emp_table e ON d.dept = e.dept
GROUP BY d.dept, d.dept_name;

This outputs perfectly formatted JSON directly from the database, ready to be sent to a REST API.

Working with XML

Parsing XML (XMLTABLE)

While JSON is the modern standard, enterprise systems (like Oracle RMS and SOA Suite) still heavily rely on XML (SOAP, RIB messages).

The equivalent to JSON_TABLE is XMLTABLE, which uses XPATH syntax.

Assuming XML payload in a column named xml_data
SQL
SELECT x.order_id, x.item_no
FROM api_logs a,
XMLTABLE(
  '/Order/Items/Item' 
  PASSING XMLTYPE(a.xml_data)
  COLUMNS 
    order_id NUMBER PATH '../../OrderID',
    item_no VARCHAR2(20) PATH 'ItemNo'
) x;

Indexing Unstructured Data

If you are querying a massive table based on a value buried deep inside a JSON payload, a Full Table Scan will be agonizingly slow. You can create a JSON Search Index to instantly locate documents.

1. Ensure the column is strictly checked for valid JSON
SQL
ALTER TABLE api_logs ADD CONSTRAINT chk_json CHECK (payload IS JSON);

-- 2. Create the index
CREATE SEARCH INDEX idx_json_payload ON api_logs(payload) FOR JSON;

Now, a query like SELECT * FROM api_logs WHERE JSON_EXISTS(payload, '$.customer?(@ == "Alice")') will use the index and return in milliseconds.

Common Gotchas

Important Gotchas

  • !

    Always add an IS JSON check constraint to your CLOB columns if they are meant to store JSON. If invalid JSON is inserted, JSON_TABLE queries will fail catastrophically. The constraint protects you and enables advanced indexing.

  • !

    Converting massive CLOBs to XMLTYPE on the fly inside a query is very CPU intensive. If you are querying the same XML elements repeatedly, parse them once upon insertion and store the extracted values in standard relational columns.

Key Takeaways

Key Takeaways

  • Use JSON_TABLE and XMLTABLE to unnest arrays and shred unstructured documents into relational formats.
  • Use JSON_OBJECT and JSON_ARRAYAGG to natively construct API payloads in SQL.
  • Always apply the IS JSON check constraint to CLOB columns storing JSON data.
  • Leverage JSON Search Indexes for high-performance lookups against specific JSON keys.
RetailCoder
All systems operational
v1.0 Live

RC:OMS

Multi-channel order management with double-entry inventory ledger. Amazon, Flipkart, Shopify, WooCommerce — one source of truth.

Launch demo →
v1.0 Live

RC:Storefront

Self-hosted headless e-commerce. Your server, your data, zero transaction fees. Native RC:OMS inventory sync.

Visit Storefront →
Pipeline

RC:Pulse

AI-powered retail analytics and demand forecasting — built natively on top of your RC:OMS and Storefront data.

Request early access →
Built in India 🇮🇳  ·  Architected by Priyanshu PandeyTalk to an engineer →