在SQL中查询列中的JSON并创建视图

在SQL中查询列中的JSON并创建视图,sql,json,sql-server,view,Sql,Json,Sql Server,View,我在其中一列中有一个带有JSON的表: 我需要创建一个以列作为JSON键的视图。因为JSON可能有不同的键,所以列的选择必须是动态的 如果您使用的是SQL 2016及更高版本,您可以使用OPONJSON函数,但是,您需要提供路径(在json代码段内),该路径不能是动态的 您可以利用以下用户定义函数从JSON提取所有元素,直到最后一级,例如JSON本身内部的JSON数组/对象 这就是功能: CREATE FUNCTION [dbo].[JsonTable] (@Json NVARCHAR(MAX

我在其中一列中有一个带有JSON的表:


我需要创建一个以列作为JSON键的视图。因为JSON可能有不同的键,所以列的选择必须是动态的

如果您使用的是SQL 2016及更高版本,您可以使用
OPONJSON
函数,但是,您需要提供路径(在json代码段内),该路径不能是动态的

您可以利用以下用户定义函数从JSON提取所有元素,直到最后一级,例如JSON本身内部的JSON数组/对象

这就是功能:

CREATE FUNCTION [dbo].[JsonTable] (@Json NVARCHAR(MAX))
RETURNS TABLE AS RETURN
WITH jsonRoot AS (
    SELECT 
        0 as parentLevel, 
        CONVERT(nvarchar(4000),NULL) as parentElementName, 
        0 AS [level], 
        [type] ,
        @Json  AS ElementName,
        [key]  as [Key],
        [value],
        ROW_NUMBER() OVER (ORDER BY (SELECT null)) AS ElementSequence
    FROM 
        OPENJSON(@Json, '$')
    UNION ALL
    SELECT 
        jsonRoot.[level] as parentLevel, 
        CONVERT(nvarchar(4000),jsonRoot.ElementName)  as parentElementName, 
        jsonRoot.[level]+1 as [level], 
        d.[type] as [type],
        CASE WHEN jsonRoot.[type] IN (4,5) THEN CONVERT(nvarchar(4000),jsonRoot.[Key]) ELSE jsonRoot.ElementName END  as ElementName,
        CASE WHEN jsonRoot.[type] IN (4) THEN jsonRoot.[Key] ELSE d.[key] END as [Key],
        d.[value],
        ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS ElementSequence
    FROM 
        jsonRoot
        CROSS APPLY OPENJSON(jsonRoot.[value], '$') d
    WHERE 
        jsonRoot.[type] IN (4,5) 

)

SELECT parentLevel , parentElementName ,[level] , [type] , ElementName , [Key] ,[value], ElementSequence
FROM jsonRoot
您可以按如下方式使用它:

SELECT type , x.*
FROM YourTable t
    CROSS APPLY dbo.JsonTable (t.JSON) x
这将把JSON分解成一个可以在存储过程中使用的表结构


试试看。

如果关键点是动态的,您希望如何创建视图?如果可以,您希望如何使用它?动态的,即可以添加新的键。视图将在存储的进程中创建,该进程将在运行时删除并重新创建视图。是否有一种方法可以在不指定键的情况下从json列中选择所有键?谢谢@hkravitz。最后,我使用OpenJson将键拆分为行值,然后使用游标循环并将这些键作为列拾取。