将 JSON 转换为 SQL - 相同 属性 的对象和字符串
Converting JSON with SQL - object and string for same property
我在使用 SQL 服务器将 JSON 数组转换为不同的输出格式时遇到了挑战...
输入:
[
{
"label": "City",
"values": [
"Test City"
]
},
{
"label": "imgTest",
"values": [
{
"identifier": "56696553-48F4-4BC5-BB43-FF4F71743EE9",
"filename": "file1.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
},
{
"identifier": "2D9106D7-71A1-440E-8255-679E8905B32E",
"filename": "file2.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
]
}
]
期望的输出:
[
{
"label": "City",
"answer": "Test City"
},
{
"label": "imgTest",
"answer": {
"filename": "file1.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
},
{
"label": "imgTest",
"answer": {
"filename": "file2.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
}
]
我发现的挑战在于将字符串和对象组合为输出中的 'answer'-属性。
请注意,这只是非常嵌套的 JSON 输入的一小部分。谢谢。
临时 tables 等是完全可能的,因为这很可能通过存储过程发生
我提到 SQL 的原因是因为这是我最熟悉的技术,并且过去已成功用于这些目的。
在图像开始播放之前,我最初的方法是构建一个具有不同层的 'label-values' 对的临时 table,然后将此 table 变成 json 和一系列嵌套的 'for json path' 语句。
但是,当我对图像数据执行此操作时,它假定内容是字符串,因此它会转义字符,这在将输出发送到下一个应用程序时会导致问题...
默认情况下,FOR JSON
子句使用 \
转义 JSON 输出中的特殊字符,通常您可以使用 JSON_QUERY()
来避免这种情况(如解释在文档中 ...JSON_QUERY returns 是一个有效的 JSON 片段。因此,FOR JSON 不会转义 [= 中的特殊字符34=] return 值).
如您所知,这里的问题是 JSON 的 $."values"
部分包含一个字符串和一个对象。此问题的可能解决方案是生成一个包含两个同名列的 table 并应用 FOR JSON AUTO
子句。 FOR JSON AUTO
的输出由 SELECT
子句中列的顺序和 SELECT
子句中引用的 table 的组合决定,所以我'我不确定此输出是“设计使然”还是只是有用的副作用。当然,如果您包含 INCLUDE_NULL_VALUES
选项,结果将包含两列的值。
JSON:
DECLARE @json nvarchar(max) = N'
[
{
"label": "City",
"values": [
"Test City"
]
},
{
"label": "imgTest",
"values": [
{
"identifier": "56696553-48F4-4BC5-BB43-FF4F71743EE9",
"filename": "file1.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
},
{
"identifier": "2D9106D7-71A1-440E-8255-679E8905B32E",
"filename": "file2.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
]
}
]'
T-SQL:
SELECT
[label],
CASE WHEN ISJSON([value]) = 0 THEN [value] END AS [answer],
JSON_QUERY(CASE WHEN ISJSON([value]) = 1 THEN [value] END) AS [answer]
FROM (
SELECT j1.[label], j2.[value]
FROM OPENJSON(@json) WITH (
[label] nvarchar(100) '$.label',
[values] nvarchar(max) '$.values' AS JSON
) j1
OUTER APPLY OPENJSON(j1.[values]) j2
) t
FOR JSON AUTO, INCLUDE_NULL_VALUES
结果:
[
{
"label":"City",
"answer":"Test City"
},
{
"label":"imgTest",
"answer":{
"identifier":"56696553-48F4-4BC5-BB43-FF4F71743EE9",
"filename":"file1.jpg",
"contentType":"image/jpg",
"bytes":"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
},
{
"label":"imgTest",
"answer":{
"identifier":"2D9106D7-71A1-440E-8255-679E8905B32E",
"filename":"file2.jpg",
"contentType":"image/jpg",
"bytes":"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
}
]
我在使用 SQL 服务器将 JSON 数组转换为不同的输出格式时遇到了挑战...
输入:
[
{
"label": "City",
"values": [
"Test City"
]
},
{
"label": "imgTest",
"values": [
{
"identifier": "56696553-48F4-4BC5-BB43-FF4F71743EE9",
"filename": "file1.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
},
{
"identifier": "2D9106D7-71A1-440E-8255-679E8905B32E",
"filename": "file2.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
]
}
]
期望的输出:
[
{
"label": "City",
"answer": "Test City"
},
{
"label": "imgTest",
"answer": {
"filename": "file1.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
},
{
"label": "imgTest",
"answer": {
"filename": "file2.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
}
]
我发现的挑战在于将字符串和对象组合为输出中的 'answer'-属性。
请注意,这只是非常嵌套的 JSON 输入的一小部分。谢谢。 临时 tables 等是完全可能的,因为这很可能通过存储过程发生
我提到 SQL 的原因是因为这是我最熟悉的技术,并且过去已成功用于这些目的。
在图像开始播放之前,我最初的方法是构建一个具有不同层的 'label-values' 对的临时 table,然后将此 table 变成 json 和一系列嵌套的 'for json path' 语句。
但是,当我对图像数据执行此操作时,它假定内容是字符串,因此它会转义字符,这在将输出发送到下一个应用程序时会导致问题...
默认情况下,FOR JSON
子句使用 \
转义 JSON 输出中的特殊字符,通常您可以使用 JSON_QUERY()
来避免这种情况(如解释在文档中 ...JSON_QUERY returns 是一个有效的 JSON 片段。因此,FOR JSON 不会转义 [= 中的特殊字符34=] return 值).
如您所知,这里的问题是 JSON 的 $."values"
部分包含一个字符串和一个对象。此问题的可能解决方案是生成一个包含两个同名列的 table 并应用 FOR JSON AUTO
子句。 FOR JSON AUTO
的输出由 SELECT
子句中列的顺序和 SELECT
子句中引用的 table 的组合决定,所以我'我不确定此输出是“设计使然”还是只是有用的副作用。当然,如果您包含 INCLUDE_NULL_VALUES
选项,结果将包含两列的值。
JSON:
DECLARE @json nvarchar(max) = N'
[
{
"label": "City",
"values": [
"Test City"
]
},
{
"label": "imgTest",
"values": [
{
"identifier": "56696553-48F4-4BC5-BB43-FF4F71743EE9",
"filename": "file1.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
},
{
"identifier": "2D9106D7-71A1-440E-8255-679E8905B32E",
"filename": "file2.jpg",
"contentType": "image/jpg",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
]
}
]'
T-SQL:
SELECT
[label],
CASE WHEN ISJSON([value]) = 0 THEN [value] END AS [answer],
JSON_QUERY(CASE WHEN ISJSON([value]) = 1 THEN [value] END) AS [answer]
FROM (
SELECT j1.[label], j2.[value]
FROM OPENJSON(@json) WITH (
[label] nvarchar(100) '$.label',
[values] nvarchar(max) '$.values' AS JSON
) j1
OUTER APPLY OPENJSON(j1.[values]) j2
) t
FOR JSON AUTO, INCLUDE_NULL_VALUES
结果:
[
{
"label":"City",
"answer":"Test City"
},
{
"label":"imgTest",
"answer":{
"identifier":"56696553-48F4-4BC5-BB43-FF4F71743EE9",
"filename":"file1.jpg",
"contentType":"image/jpg",
"bytes":"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
},
{
"label":"imgTest",
"answer":{
"identifier":"2D9106D7-71A1-440E-8255-679E8905B32E",
"filename":"file2.jpg",
"contentType":"image/jpg",
"bytes":"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"
}
}
]