使用没有嵌套数组或转义字符的 JSON_MODIFY 的复杂 JSON (WITHOUT_ARRAY_WRAPPER)

Complex JSON using JSON_MODIFY without nested arrays or escape characters (WITHOUT_ARRAY_WRAPPER)

我正在使用 JSON_MODIFY 构建复杂的 JSON。从 MySQL 开始,我正在努力使用 SQL 服务器提供的 JSON 功能。我遇到的问题是 SQL 服务器似乎在数组中构造所有 JSON 对象。有 WITHOUT_ARRAY_WRAPPER 机制,它似乎应该做我想做的事;有两个不良后果。

  1. 它只有 returns 一个结果,具体取决于它的使用方式
  2. 结果是一个带有转义字符的字符串

我构建了一个简单的查询来说明我的需求和问题。

查询 1

SELECT JSON_MODIFY(
    JSON_QUERY('{"definitions": {"id": "INT", "name": "VARCHAR(23)"}}'),
    'append $.data',
    (
        SELECT * FROM (
            SELECT 1 AS id, '123abc' AS "name" UNION
            SELECT 2 AS id, '234bcd' AS "name"
        ) AS "data"
        FOR JSON PATH, WITHOUT_ARRAY_WRAPPER 
    ) 
) AS "data";

输出 1

{
   "definitions":{
      "id":"INT",
      "name":"VARCHAR(23)"
   },
   "data":[
      "{\"id\":1,\"name\":\"123abc\"},{\"id\":2,\"name\":\"234bcd\"}"
   ]
}

查询 2

SELECT JSON_MODIFY(
    JSON_QUERY('{"definitions": {"id": "INT", "name": "VARCHAR(23)"}}'),
    'append $.data',
    (
        SELECT * FROM (
            SELECT 1 AS id, '123abc' AS "name" UNION
            SELECT 2 AS id, '234bcd' AS "name"
        ) AS "data"
        FOR JSON PATH
    ) 
) AS "data";

输出 2

{
   "definitions":{
      "id":"INT",
      "name":"VARCHAR(23)"
   },
   "data":[
      [
         {"id":1, "name":"123abc"},
         {"id":2, "name":"234bcd"}
      ]
   ]
}

"In this particular object the data element is an array of arrays--You'll want to use the first and only the first element to access the actual array of data."

我天真地尝试了 JSON_MODIFYJSON_QUERYCONCAT 的许多不同组合,但都无济于事。在 data 中没有双数组的情况下,如何正确使用 JSON_MODIFY 获得以下输出?

{
   "definitions":{
      "id":"INT",
      "name":"VARCHAR(23)"
   },
   "data":[
     {"id":1, "name":"123abc"},
     {"id":2, "name":"234bcd"}
   ]
}

通过反复试验,我找到了解决方案。

  1. JSON_MODIFY 语句
  2. path 参数中删除了 append 关键字
  3. FOR JSON 语句中删除了 WITHOUT_ARRAY_WRAPPER 参数。

现在结果符合预期,我不需要向任何消费者解释“只需使用数据[0]”

查询

SELECT JSON_MODIFY(
    JSON_QUERY('{"definitions": {"id": "INT", "name": "VARCHAR(23)"}}'),
    '$.data',
    (
        SELECT * FROM (
            SELECT 1 AS id, '123abc' AS "name" UNION
            SELECT 2 AS id, '234bcd' AS "name"
        ) AS "data"
        FOR JSON PATH
    ) 
) AS "data";

产生以下输出

{
   "definitions":{
      "id":"INT",
      "name":"VARCHAR(23)"
   },
   "data":[
     {"id":1, "name":"123abc"},
     {"id":2, "name":"234bcd"}
   ]
}

您试图 JSON_MODIFY 一个现有对象是想多了。

如有必要,在子查询中构造您需要的 definitionsdata 属性。

然后再次使用FOR JSON获取外部对象。

SELECT 
    definitions = JSON_QUERY('{"id": "INT", "name": "VARCHAR(23)"}'),
    data = 
    (
        SELECT id, name
        FROM (VALUES
            (1, '123abc'),
            (2, '234bcd')
        ) v(id, name)
        FOR JSON PATH
    )
FOR JSON PATH;

SQL Fiddle