Parse JSON in Oracle to extract, filter, and join JSON data with relational tables using JSON_VALUE, JSON_QUERY, and JSON_TABLE.
Applications often store semi-structured attributes—shopping cart details, payment metadata, or address formats—as JSON. Oracle’s JSON functions let you filter, extract, and join this data without unloading it into separate columns, keeping queries simple and performant.
JSON_VALUE returns a scalar (number, string, date, Boolean) from a JSON column. Use it when you only need one value, such as pulling the city
from a shipping address stored in Orders.extra_info
.
SELECT id,
JSON_VALUE(extra_info, '$.shipping.city') AS city
FROM Orders
WHERE order_date >= DATE '2024-01-01';
JSON_QUERY returns JSON fragments (objects or arrays). Wrap the result in FORMAT JSON
when you need to pass it to APIs or client code.
SELECT id,
JSON_QUERY(extra_info, '$.shipping' RETURNING CLOB FORMAT JSON) AS shipping_json
FROM Orders
WHERE total_amount > 100;
JSON_TABLE turns JSON arrays or objects into a relational table you can join or filter. It’s perfect for line-item analysis in ecommerce.
SELECT o.id AS order_id,
jt.product_id,
jt.quantity
FROM Orders o,
JSON_TABLE(o.extra_info, '$.items[*]' COLUMNS (
product_id NUMBER PATH '$.productId',
quantity NUMBER PATH '$.qty'
)) jt;
Combine JSON_TABLE output with regular tables to enrich reports, validate prices, or detect out-of-stock items.
SELECT c.name AS customer,
p.name AS product,
jt.quantity,
p.stock
FROM Orders o
JOIN Customers c ON c.id = o.customer_id
CROSS JOIN JSON_TABLE(o.extra_info, '$.items[*]' COLUMNS (
product_id NUMBER PATH '$.productId',
quantity NUMBER PATH '$.qty'
)) jt
JOIN Products p ON p.id = jt.product_id
WHERE p.stock < jt.quantity;
1) Add a check constraint IS JSON
to ensure valid data. 2) Create functional indexes on frequently queried paths using JSON_VALUE
. 3) Cast results to proper data types for accurate comparisons. 4) Use KEEP
or ERROR ON ERROR
options to control bad data behavior.
Yes. Create a functional index on JSON_VALUE, e.g., CREATE INDEX idx_city ON Orders (JSON_VALUE(extra_info, '$.shipping.city'));
Add CHECK (extra_info IS JSON)
to ensure only valid JSON is stored.
No. JSON_TABLE is optimized in SQL and can leverage indexes, making it faster and simpler than procedural loops.