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.
我有一个 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.