发现的怪异 JSON、SQL 服务器和 OPENJSON

Discovery's Weird JSON, SQL Server, and OPENJSON

我正在使用 Discovery 中的 API 从我们的虚拟机中提取一些信息,但是 JSON 由于某些原因在一个节点中有标题而在另一个节点中有值,并且它们是正方形的括号,我很难得到最终结果。

这是 JSON

的 watered-down 版本
DECLARE @JSON nvarchar(max) = N'[
    {
        "headings": [
            "vm_type",
            "Hostname"
            ],
        "results": [
            [
                "AWS EC2 Instance",
                null
            ],
            [
                "AWS EC2 Instance",
                null
            ]
        ]
    }
]'

SET @JSON = SUBSTRING(@JSON,2,LEN(@JSON) - 2)
SELECT *
FROM OPENJSON(@JSON)

SELECT *
FROM OPENJSON(@JSON,'$.results')

有没有办法将其变成 table,标题作为列名,结果的顺序与其值相同?

你有一个数组数组,所以这实际上是一个动态枢轴。

要进行动态枢轴,您需要动态 SQL。最简单的数据透视方法通常不是使用 PIVOT,而是使用 MAX(CASE

的条件聚合
DECLARE @sql nvarchar(max) = N'
SELECT
  ' + (
    SELECT STRING_AGG(
        QUOTENAME(j.value) + N' = MAX(CASE WHEN j2.[key] = ' + j.[key] + ' THEN j2.value END)',
        ',
  ') WITHIN GROUP (ORDER BY j.[key])
    FROM OPENJSON(@JSON, '$[0].headings') j
) + '
FROM OPENJSON(@JSON, ''$[0].results'') j1
CROSS APPLY OPENJSON(j1.value) j2
GROUP BY
  j1.[key];
';

PRINT @sql; --for testing

EXEC sp_executesql
  @sql,
  N'@JSON nvarchar(max)',
  @JSON = @JSON;

db<>fiddle

注意正确使用 QUOTENAME 来引用列名,并使用 sp_executesql 和参数来传递实际数据,而不是直接将其注入查询文本。