Json 到 table 没有明确的键名

Json to table without explicit key names

我有一个 table 和一个 VARCHAR(MAX) 列,它存储 JSON 个键值对。 JSON 文档模式只是不同数量的键值对,没有嵌套,也没有数组。

我希望构建一个查询,以表格格式返回 JSON, 使用命名元素很容易(请参阅下面的 WITH 子句):

DECLARE @MYJSONTABLE TABLE (ID INT IDENTITY NOT NULL PRIMARY KEY, MYDATA NVARCHAR(max) null)
INSERT INTO @MYJSONTABLE
(
    MYDATA
)
VALUES
(N'{"id": 2, "info": "some info", "age": 25}'),
(N'{"id": 5, "info": "other info", "dob": "2005-11-04T12:00:00"}')

SELECT p.ID,MYDATA.*
FROM @MYJSONTABLE p
CROSS APPLY 
OPENJSON(p.MYDATA)
WITH (
    id INT 'strict $.id',
    info NVARCHAR(50) '$.info',
    age INT,
    dateOfBirth DATETIME2 '$.dob'
) AS MYDATA

虽然输出正是我想要的, 我对上述解决方案的问题是,我也不知道 JSON 文档中的键名,也不知道有多少,但仍然希望 return 它们全部采用相同的表格格式。

如果我省略上面的 WITH 子句,查询将执行 return 所有键值对,但输出变为“垂直”并且 JSON 中的每个键生成一个新行。

是否可以将上述查询修改为动态的,并且 return 所有键值对而不显式指定 JSON 键名?

也许这样的东西对你有用。

这使用 CTE 从您的 JSON 获取 DISTINCT 密钥。然后进行字符串聚合创建动态语句,从PRINT语句可以看出

请注意,对于您的示例数据,dob 未返回 ,因为它在初始 JSON 定义之外。如果移除第一个右大括号 (}),则会显示该列。

DECLARE @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

DECLARE @Delimiter nvarchar(50) = N',' + @CRLF + N'                      ';

WITH Keys AS(
    SELECT DISTINCT J.[key]
    FROM dbo.YourTable YT
         CROSS APPLY OPENJSON(YT.JsonColumn) J)
SELECT @SQL = N'SELECT YT.ID,' + @CRLF +
              N'       J.*' + @CRLF +
              N'FROM dbo.YourTable YT' + @CRLF +
              N'     CROSS APPLY OPENJSON(YT.JsonColumn)' + @CRLF +
              N'                 WITH(' +
              STRING_AGG(QUOTENAME(K.[key]) + N' nvarchar(100)', @Delimiter) + N') J;'
FROM Keys K;

PRINT @SQL;
EXEC sys.sp_executesql @SQL;

请注意,这 不会 使用 table 变量,除非您创建 table 类型然后传递 TYPE 作为 sys.sp_executesql 的参数。这就是为什么上面假设 真实 table.