使用没有嵌套数组或转义字符的 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
机制,它似乎应该做我想做的事;有两个不良后果。
- 它只有 returns 一个结果,具体取决于它的使用方式
- 结果是一个带有转义字符的字符串
我构建了一个简单的查询来说明我的需求和问题。
查询 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"}
]
]
}
查询 1
data
对象是一个数组(这是预期的),但问题是数组中的内容...带有转义字符的单个字符串。
查询 2
data
对象是一个数组,其中包含一个数组。为了访问实际的数据数组,我会使用类似 for each obj in data[0]...
的东西。这带来的问题是,对于任何使用 JSON 对象的人,我必须告诉 他们:
"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_MODIFY
、JSON_QUERY
和 CONCAT
的许多不同组合,但都无济于事。在 data
中没有双数组的情况下,如何正确使用 JSON_MODIFY
获得以下输出?
{
"definitions":{
"id":"INT",
"name":"VARCHAR(23)"
},
"data":[
{"id":1, "name":"123abc"},
{"id":2, "name":"234bcd"}
]
}
通过反复试验,我找到了解决方案。
- 从
JSON_MODIFY
语句 的 path 参数中删除了 append
关键字
- 从
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
一个现有对象是想多了。
如有必要,在子查询中构造您需要的 definitions
和 data
属性。
然后再次使用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;
我正在使用 JSON_MODIFY
构建复杂的 JSON。从 MySQL 开始,我正在努力使用 SQL 服务器提供的 JSON 功能。我遇到的问题是 SQL 服务器似乎在数组中构造所有 JSON 对象。有 WITHOUT_ARRAY_WRAPPER
机制,它似乎应该做我想做的事;有两个不良后果。
- 它只有 returns 一个结果,具体取决于它的使用方式
- 结果是一个带有转义字符的字符串
我构建了一个简单的查询来说明我的需求和问题。
查询 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"}
]
]
}
查询 1
data
对象是一个数组(这是预期的),但问题是数组中的内容...带有转义字符的单个字符串。查询 2
data
对象是一个数组,其中包含一个数组。为了访问实际的数据数组,我会使用类似for each obj in data[0]...
的东西。这带来的问题是,对于任何使用 JSON 对象的人,我必须告诉 他们:
"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_MODIFY
、JSON_QUERY
和 CONCAT
的许多不同组合,但都无济于事。在 data
中没有双数组的情况下,如何正确使用 JSON_MODIFY
获得以下输出?
{
"definitions":{
"id":"INT",
"name":"VARCHAR(23)"
},
"data":[
{"id":1, "name":"123abc"},
{"id":2, "name":"234bcd"}
]
}
通过反复试验,我找到了解决方案。
- 从
JSON_MODIFY
语句 的 path 参数中删除了 - 从
FOR JSON
语句中删除了WITHOUT_ARRAY_WRAPPER
参数。
append
关键字
现在结果符合预期,我不需要向任何消费者解释“只需使用数据[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
一个现有对象是想多了。
如有必要,在子查询中构造您需要的 definitions
和 data
属性。
然后再次使用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;