Не используйте регулярные выражения; используйте JSON_TABLE
или JSON_VALUE
для анализа JSON:
Oracle 18 c Настройка :
CREATE TABLE test_data (
id INTEGER,
value VARCHAR2(4000)
);
INSERT INTO test_data ( id, value )
SELECT 1, '{"layerId":"nameOfLayer","layerParams":{"some":"unnecessary data"}}' FROM DUAL UNION ALL
SELECT 2, '{"layerParams":{"layerId":"NOT THIS ONE!"},"layerId":"nameOfLayer"}' FROM DUAL UNION ALL
SELECT 3, '{"layerId":"Name with \"Quotes\"","layerParams":{"layerId":"NOT THIS ONE!"}}' FROM DUAL;
Запрос 1 :
SELECT t.id,
j.layerId
FROM test_data t
CROSS JOIN
JSON_TABLE(
t.value,
'$'
COLUMNS (
layerId VARCHAR2(50) PATH '$.layerId'
)
) j
Запрос 2 :
Если вам нужно только одно значение, вы можете использовать JSON_VALUE
:
SELECT id,
JSON_VALUE( value, '$.layerId' ) AS layerId
FROM test_data
Выход :
Оба выхода:
ID | LAYERID
-: | :-----------------
1 | nameOfLayer
2 | nameOfLayer
3 | Name with "Quotes"
Запрос 3 :
Вы можете попробовать регулярные выражения, но они не всегда работают должным образом:
SELECT id,
REPLACE(
REGEXP_SUBSTR( value, '[{,]"layerId":"((\\"|[^"])*)"', 1, 1, NULL, 1 ),
'\"',
'"'
) AS layerID
FROM test_data
Вывод :
ID | LAYERID
-: | :-----------------
1 | nameOfLayer
2 | NOT THIS ONE!
3 | Name with "Quotes"
Так что если вы может гарантировать, что никто не собирается помещать данные в базу данных, где JSON находится в другом порядке, чем это может сработать; однако спецификация JSON позволяет парам ключ-значение располагаться в любом порядке, поэтому регулярные выражения не являются общим решением, которое будет анализировать каждую строку JSON. Вы должны использовать правильный JSON синтаксический анализатор, и есть сторонние решения, доступные для Oracle 11g, или вы можете обновить до Oracle 12 c, где есть собственное решение.
дБ <> скрипка здесь