Oracle Database ofrece soporte nativo para JSON desde la versión 12c (2014).
VARCHAR2
, CLOB
, BLOB
.JSON
.CHECK ... IS JSON
.CREATE TABLE productos (
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
nombre VARCHAR2(100),
datos CLOB CHECK (datos IS JSON)
);
Con IS JSON
, Oracle valida que la columna contenga JSON válido.
INSERT INTO productos (nombre, datos) VALUES
('Teclado', '{"codigo":101,"precio":1200.50,"disponible":true,"tags":["periférico","oferta"]}');
INSERT INTO productos (nombre, datos) VALUES
('Mouse', '{"codigo":102,"precio":850.75,"disponible":false}');
Oracle permite consultar con JSON_VALUE
, JSON_QUERY
y dot-notation (21c+). Docs: JSON en Oracle.
Extraer valores escalares (JSON_VALUE)
SELECT
nombre,
JSON_VALUE(datos, '$.codigo') AS codigo,
JSON_VALUE(datos, '$.precio') AS precio
FROM productos;
Extraer objetos/arrays (JSON_QUERY)
SELECT JSON_QUERY(datos, '$.tags') AS tags
FROM productos
WHERE nombre = 'Teclado';
-- Resultado: ["periférico", "oferta"]
SELECT nombre, JSON_VALUE(datos, '$.precio') AS precio
FROM productos
WHERE JSON_VALUE(datos, '$.precio') > 1000;
Con JSON_MERGEPATCH se modifican documentos JSON:
UPDATE productos
SET datos = JSON_MERGEPATCH(datos, '{"precio": 900}')
WHERE nombre = 'Mouse';
Con JSON_TRANSFORM (21c+):
UPDATE productos
SET datos = JSON_TRANSFORM(datos, SET '$.stock' = 50)
WHERE nombre = 'Teclado';
UPDATE productos
SET datos = JSON_TRANSFORM(datos, REMOVE '$.tags')
WHERE nombre = 'Teclado';
Extraer elementos individuales con JSON_TABLE
:
SELECT t.nombre, jt.value AS tag
FROM productos t,
JSON_TABLE(t.datos, '$.tags[*]' COLUMNS (value VARCHAR2(50) PATH '$')) jt
WHERE t.nombre = 'Teclado';
-- Resultado: Teclado | periférico / Teclado | oferta
SELECT JSON_OBJECT(
'id' VALUE id,
'nombre' VALUE nombre,
'datos' VALUE datos
) AS producto_json
FROM productos;
-- También existe JSON_ARRAYAGG para crear arrays.
Oracle soporta functional indexes para acelerar consultas sobre JSON.
CREATE INDEX idx_precio_json
ON productos (JSON_VALUE(datos, '$.precio'));
-- Consultas por precio serán más rápidas.
CREATE TABLE pedidos (
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
cliente VARCHAR2(100),
detalle CLOB CHECK (detalle IS JSON)
);
INSERT INTO pedidos (cliente, detalle) VALUES
('María', '{
"items": [
{"producto": "Notebook", "cantidad": 1, "precio": 2500.00},
{"producto": "Mouse", "cantidad": 2, "precio": 850.75}
],
"total": 4201.50
}');
-- Consultar todos los items con JSON_TABLE
SELECT p.cliente, i.producto, i.cantidad, i.precio
FROM pedidos p,
JSON_TABLE(p.detalle, '$.items[*]'
COLUMNS (
producto VARCHAR2(50) PATH '$.producto',
cantidad NUMBER PATH '$.cantidad',
precio NUMBER PATH '$.precio'
)
) i;
Ventajas
IS JSON
).JSON_VALUE
, JSON_QUERY
, JSON_TABLE
).JSON_OBJECT
, JSON_ARRAYAGG
).Desventajas
CHECK ... IS JSON
garantizan integridad.JSON_VALUE
(escalares), JSON_QUERY
(objetos/arrays), JSON_TABLE
(tablas de JSON), JSON_MERGEPATCH
/JSON_TRANSFORM
(modificar documentos).