PL/SQL20 min readBy Priyanshu Pandey

Native JSON Processing in PL/SQL: The Modern Oracle Guide

Learn how to natively parse, generate, and query JSON data directly inside Oracle PL/SQL. Master JSON_OBJECT, JSON_ARRAY, JSON_TABLE, and dot-notation for modern REST API integrations.

Integrations · PL/SQL Mastery Series

Native JSON in PL/SQL: JSON_TABLE & Payload Generation

Relational databases and NoSQL document structures used to be enemies. With Oracle's native JSON support, you can seamlessly shred complex JSON payloads into relational tables and construct nested JSON strings directly from SQL queries.

20 min read📅July 20, 2026✍️Priyanshu Pandey📚PL/SQL Mastery Series
GENERATION

1. Generating JSON Payloads

When building microservices (e.g., exposing an Oracle Retail API via ORDS), you need to convert relational data into JSON. Forget string concatenation; Oracle provides native generation functions.

Creating JSON Objects and Arrays

  • JSON_OBJECT(): Creates a key-value JSON object.
  • JSON_ARRAY(): Creates a JSON array.
  • JSON_ARRAYAGG(): Aggregates multiple relational rows into a single JSON array.
Generating a Nested JSON Payload
SQL
SELECT JSON_OBJECT(
         'department_id' VALUE d.department_id,
         'department_name' VALUE d.department_name,
         'employees' VALUE JSON_ARRAYAGG(
             JSON_OBJECT(
                 'emp_id' VALUE e.employee_id,
                 'name' VALUE e.first_name || ' ' || e.last_name
             )
         )
       ) AS dept_json
FROM departments d
LEFT JOIN employees e ON d.department_id = e.department_id
GROUP BY d.department_id, d.department_name;

Output:

{
  "department_id": 10,
  "department_name": "Administration",
  "employees": [
    {"emp_id": 200, "name": "Jennifer Whalen"}
  ]
}
PARSING

2. Shredding JSON with JSON_TABLE

If you receive a massive JSON payload from a REST endpoint and need to insert it into relational tables, JSON_TABLE is a lifesaver. It acts as a table function, projecting JSON elements into relational columns.

Mapping JSON to Columns
SQL
DECLARE
    v_payload CLOB := '
    {
      "order_id": 99887,
      "lines": [
        {"item": "SKU123", "qty": 5},
        {"item": "SKU456", "qty": 10}
      ]
    }';
BEGIN
    FOR r IN (
        SELECT jt.*
        FROM DUAL,
             JSON_TABLE(v_payload, '$'
                 COLUMNS (
                     order_id NUMBER PATH '$.order_id',
                     NESTED PATH '$.lines[*]' COLUMNS (
                         item_id VARCHAR2(20) PATH '$.item',
                         quantity NUMBER PATH '$.qty'
                     )
                 )
             ) jt
    ) LOOP
        DBMS_OUTPUT.PUT_LINE('Order: ' || r.order_id || ' Item: ' || r.item_id);
    END LOOP;
END;

How it works:

  • '$' is the root context path.
  • PATH '$.order_id' navigates down the JSON tree to find the value.
  • NESTED PATH '$.lines[*]' iterates through the JSON array, creating a new relational row for every element in the array.
VALIDATION

3. Storing and Validating JSON

Prior to Oracle 21c (which introduced the native JSON datatype), JSON was stored in CLOB or VARCHAR2 columns. To ensure bad data isn't inserted, you use the IS JSON check constraint.

IS JSON Constraint
SQL
CREATE TABLE integration_payloads (
    message_id NUMBER PRIMARY KEY,
    payload CLOB CONSTRAINT ensure_json CHECK (payload IS JSON)
);

Once the constraint is in place, you can query the data using simple dot notation:

SELECT p.payload.order_id, p.payload.customer.name
FROM integration_payloads p;

Key Takeaways

    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 →