WITH t AS (
SELECT 1 ID, '$Name:micheal$dept:$sal:$dob:1.0$place:india$' s FROM dual
/*
union all
SELECT 2 ID, '$Name:micheal$dept:$sal:$dob:1.0$place:india$' s FROM dual
*/
)
SELECT ID, regexp_substr(token, '[^:]+', 1, 1) name_
, regexp_substr(token, '[^:]+', 1, 2) value_
FROM (
SELECT id, regexp_substr(s, '[^\$]+', 1, lvl) token, lvl
FROM t JOIN
(
SELECT LEVEL lvl FROM dual
CONNECT BY LEVEL < (SELECT MAX(LENGTH(s) - LENGTH(REPLACE(s, '$'))) FROM t)
) x ON LENGTH(s) - LENGTH(REPLACE(s, '$')) > lvl
)
order by id, lvl;
1) Рассчитать количество жетонов, поделенное на $: LENGTH(s) - LENGTH(REPLACE(s, '$')
2) Я написал вариант для таблицы (предположим, что есть несколько рядов для синтаксического анализа)
3) CONNECT BY LEVEL < max
- генерировать числа от 1 до максимального количества $ возможно в таблице
4) Регистрация номера с таблицей для разбора каждого маркеров с помощью REGEXP_SUBSTR (,,) встречаемости
5) снова Разбираем с раздельным имя/значение
Чтобы разобрать только одну строку:
SELECT regexp_substr(token, '[^:]+', 1, 1) name_,
regexp_substr(token, '[^:]+', 1, 2) value_
FROM (
SELECT regexp_substr(s, '[^\$]+', 1, lvl) token, lvl
FROM (
SELECT s, LEVEL lvl FROM (SELECT '$Name:micheal$dept:$sal:$dob:1.0$place:india$' s FROM dual)
CONNECT BY LEVEL < LENGTH(s) - LENGTH(REPLACE(s, '$'))
)
);
Он работал. Спасибо. Но почему это повторяется дважды? – Crazy2crack
@CrazeaboutLife Я думал, что у вас есть таблица с несколькими рядами. Если у вас есть только одна строка, это можно сделать проще (нет необходимости присоединяться). – Multisync
@CrazeaboutLife Я добавил запрос только для одной строки (не таблицы) – Multisync