By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
WITH
data AS (SELECT CAST('{"f1":["v1","v2"],"f2":"v3"}' AS varchar(max)) AS ResponseJSON),
parser AS
(
SELECT
Level = 1,
OpenClose = 1,
P = p.P,
S = SUBSTRING(d.ResponseJSON, 1, NULLIF(p.P, 0) - 1),
C = SUBSTRING(d.ResponseJSON, NULLIF(p.P, 0), 1),
ResponseJSON = SUBSTRING(d.ResponseJSON, NULLIF(p.P, 0) + 1, 999999)
FROM
data AS d
CROSS APPLY (SELECT PATINDEX('%[[{]%', d.ResponseJSON)) AS p (P)
UNION ALL
SELECT
Level = ISNULL(d.OpenClose - 1, 0) + d.Level + ISNULL(oc.OpenClose, 0),
OpenClose = oc.OpenClose,
P = d.P + p.P,
S = SUBSTRING(d.ResponseJSON, 1, NULLIF(p.P, 0) - 1),
C = c.C,
ResponseJSON = SUBSTRING(d.ResponseJSON, NULLIF(p.P, 0) + 1, 999999)
FROM
parser AS d
CROSS APPLY (SELECT PATINDEX('%[[{}:,]%' COLLATE Latin1_General_BIN2, d.ResponseJSON)) AS p (P)
CROSS APPLY (SELECT SUBSTRING(d.ResponseJSON, NULLIF(p.P, 0), 1)) AS c (C)
CROSS APPLY (SELECT CASE WHEN c.C IN ('[', '{') THEN 1 WHEN c.C IN (']', '}') THEN 0 END) AS oc (OpenClose)
WHERE 1=1
AND p.P <> 0
)
SELECT
*
FROM
parser
OPTION
(MAXRECURSION 0)
Level | OpenClose | P | S | C | ResponseJSON |
---|---|---|---|---|---|
1 | 1 | 1 | { | "f1":["v1","v2"],"f2":"v3"} | |
1 | null | 6 | "f1" | : | ["v1","v2"],"f2":"v3"} |
2 | 1 | 7 | [ | "v1","v2"],"f2":"v3"} | |
2 | null | 12 | "v1" | , | "v2"],"f2":"v3"} |
2 | null | 18 | "v2"] | , | "f2":"v3"} |
2 | null | 23 | "f2" | : | "v3"} |
2 | 0 | 28 | "v3" | } |