如何从 SQL 服务器中的动态节点加载 OPENJSON

How to load OPENJSON from Dynamic Nodes in SQL Server

我通过 REST API 接收的 JSON 格式包含我无法加载到 OPENJSON 中的动态节点。 JSON 响应来自第三方,我无法更改它。请参阅下面的示例并注意日期被用作节点:

{
    "Meta Data": {
        "1. Information": "API JSON",
        "2. TYPE": "JSON",
    },
    "TSD": {
        "2019-08-13": {
            "value1": "136.0500",
            "value2": "137.7400"
        },
        "2019-08-12": {
            "value1": "137.0700",
            "value2": "137.8600"

        },
        "2019-08-09": {
            "value1": "138.6100",
            "value2": "139.3800"
        }
    }
}

如果我知道确切的日期,我可以使用以下代码获取特定节点:

 SELECT [value1], [value2]
 FROM OPENJSON(@json, '$."TSD"."2019-08-13"')
 WITH (
    [value1] numeric(20,10),
    [value2] numeric(20,10),
    )

然而,这没有帮助,因为我无法提前知道日期,并且使用此方法一次只能 select 一个日期节点。

如何在事先不知道节点名称的情况下引用这些动态日期?

您需要调用 OPENJSON() 两次。第一次调用使用默认模式,结果是 table 和 keyvaluetype 列(key 列包含日期)。第二次调用是使用具有定义列的显式模式。

请注意,您需要删除 "2. TYPE": "JSON" 之后多余的 ,

JSON:

DECLARE @json nvarchar(max) = N'{
    "Meta Data": {
        "1. Information": "API JSON",
        "2. TYPE": "JSON"
    },
    "TSD": {
        "2019-08-13": {
            "value1": "136.0500",
            "value2": "137.7400"
        },
        "2019-08-12": {
            "value1": "137.0700",
            "value2": "137.8600"

        },
        "2019-08-09": {
            "value1": "138.6100",
            "value2": "139.3800"
        }
    }
}'

声明:

SELECT 
   j1.[key] AS [Date],
   j2.value1,
   j2.value2
FROM OPENJSON(@json, '$.TSD') j1
CROSS APPLY OPENJSON(j1.[value])  WITH (
   value1 numeric(20, 4) '$.value1',
   value2 numeric(20, 4) '$.value2'
) j2

输出:

-------------------------------
Date        value1      value2
-------------------------------
2019-08-13  136.0500    137.7400
2019-08-12  137.0700    137.8600
2019-08-09  138.6100    139.380