MySQL JSON 解析 - 转义 Json-within-Json

MySQL JSON Parsing - Escaped Json-within-Json

我在使用内置 MySQL JSON 函数从嵌套在 JSON 字符串中的 JSON 字符串中解析出值时遇到问题。

这是一个示例:

{
  "SucceededAt": "2022-01-18T07:54:50.5548083Z",
  "PerformanceDuration": "1463",
  "Latency": "91",
  "Result": "\"Request Body: {\\"request\\":[{\\"id\\":[{\\"value\\":\\"1\\"}],\\"roles\\":{\\"receiver\\":{\\"id\\":[{\\"value\\":\\"1115559991\\"}]}},\\"details\\":{\\"adjustmentAmount\\":{\\"value\\":7800}}}]}, Response Body:{\\"response\\":[{\\"id\\":[{\\"value\\":\\"1\\"}],\\"parts\\":{\\"specification\\":{\\"characteristicsValue\\":[{\\"characteristicName\\":\\"MSISDN\\",\\"value\\":\\"9998885556\\"},{\\"characteristicName\\":\\"ResponseCode\\",\\"value\\":\\"1000\\"},{\\"characteristicName\\":\\"ResponseDescription\\",\\"value\\":\\"Operation successfully.\\"}]}}}]}\""
}

我想从“结果”中获取“请求”和“响应”key/value 对 key/value。

当我使用 SELECT JSON_VALUE(Data, '$.Result') FROM [...] 从“Result”键中提取值时,它 returns 转义字符串值(再次是 json-within-json,我认为)如下(带双引号字符):

"Request Body: {\"request\":[{\"id\":[{\"value\":\"1\"}],\"roles\":{\"receiver\":{\"id\":[{\"value\":\"114787601\"}]}},\"details\":{\"adjustmentAmount\":{\"value\":7800}}}]}, Response Body:{\"response\":[{\"id\":[{\"value\":\"1\"}],\"parts\":{\"specification\":{\"characteristicsValue\":[{\"characteristicName\":\"MSISDN\",\"value\":\"114787601\"},{\"characteristicName\":\"ResponseCode\",\"value\":\"1000\"},{\"characteristicName\":\"ResponseDescription\",\"value\":\"Operation successfully.\"}]}}}]}"

这是我卡住的步骤。

有没有办法使用内置的 MySQL JSON 函数来做到这一点?

您可以使用 JSON_UNQUOTE 获取 JSON_VALUE 返回的 json 字符串并将其转换为原始字符串值。然后使用 substring_index 解析请求正文:和响应正文:,假设它们的格式与您的示例中所示完全相同(请求的冒号后真的有 space 而不是响应??):

select
    substring_index(substring_index(json_unquote(json_value(Data, '$.Result')),', Response Body:',1),'Request Body: ',-1) as request,
    substring_index(json_unquote(json_value(Data, '$.Result')),', Response Body:',-1) as response
from foo;

fiddle

substring_index(foo,bar,1) 获取 foo 中第一个 bar 之前的所有内容(或者 returns 如果找不到 bar 则获取整个字符串)。 substring_index(foo,bar,-1) 获取 foo 中最后一个小节之后的所有内容(或者 returns 如果没有找到小节,则获取整个字符串)。