0

REST API 呼び出しの応答として、非常に構造化されていない JSON 文字列があります。

{
    "info": "Test Json Structure",
    "Owner": "Self-Owned",
    "managedObjects": [{
            "Name": "Device1",
            "Class": "A"
        }, {
            "Name": "Device2",
            "Class_145": "Ax01",
            "Class_11": "B",
            "Type_125478": {
                "Model": "1",
                "Manufacturer": "External"
            },
            "Type_SD": {
                "Model": "00",
                "Manufacturer": "Internal"
                }
        }, {
            "Name": "Device3",
            "Class_x": "Cx11",
            "Class_T": "C8Y",
            "Type": {
                "Model": "1x",
                "Manufacturer": "Internal"
            }
        }
    ]
}

すべての子要素がテーブルの列を表すように、T-SQL を使用してこのオブジェクトを動的に解析するにはどうすればよいですか? さらに重要なことはType、 、Type_125478Type_SDオブジェクトをどのように処理するかです。実際には同じ構造 ( Model, Manufacturer) ですが、名前が異なる場合もあります。また、デバイスが新しい識別子 ( ) を送信する可能性があることにも注意してType_XYZください。これは以前には存在しませんでしたが、幸いなことに同じ構造 ( Model, Manufacturer) を持っています。

4

1 に答える 1

2

次のようなものを使用して、すべてを表形式の構造に分解し、これを続行できます (SQL Server バージョン v2016+ が必要です)。

DECLARE @YourJSON NVARCHAR(MAX)=
N'{
    "info": "Test Json Structure",
    "Owner": "Self-Owned",
    "managedObjects": [{
            "Name": "Device1",
            "Class": "A"
        }, {
            "Name": "Device2",
            "Class_145": "Ax01",
            "Class_11": "B",
            "Type_125478": {
                "Model": "1",
                "Manufacturer": "External"
            },
            "Type_SD": {
                "Model": "00",
                "Manufacturer": "Internal"
                }
        }, {
            "Name": "Device3",
            "Class_x": "Cx11",
            "Class_T": "C8Y",
            "Type": {
                "Model": "1x",
                "Manufacturer": "Internal"
            }
        }
    ]
}';

-- クエリ

SELECT A.info
      ,A.[Owner]
      ,C.[key] AS TagName
      ,CASE WHEN D.Model IS NULL THEN C.[value] END AS TagValue 
      ,D.Model
      ,D.Manufacturer
FROM OPENJSON(@YourJSON)
WITH(info NVARCHAR(MAX)
    ,[Owner] NVARCHAR(MAX)
    ,managedObjects NVARCHAR(MAX) AS JSON) A
OUTER APPLY OPENJSON(A.managedObjects) B
OUTER APPLY OPENJSON(B.[value]) C
OUTER APPLY OPENJSON(CASE WHEN ISJSON(C.[value])=1 THEN C.[value] END) 
WITH (Model NVARCHAR(MAX)
     ,Manufacturer NVARCHAR(MAX))D;

- 結果

+---------------------+------------+-------------+----------+-------+--------------+
| info                | Owner      | TagName     | TagValue | Model | Manufacturer |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Name        | Device1  |       |              |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class       | A        |       |              |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Name        | Device2  |       |              |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class_145   | Ax01     |       |              |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class_11    | B        |       |              |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Type_125478 |          | 1     | External     |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Type_SD     |          | 00    | Internal     |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Name        | Device3  |       |              |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class_x     | Cx11     |       |              |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Class_T     | C8Y      |       |              |
+---------------------+------------+-------------+----------+-------+--------------+
| Test Json Structure | Self-Owned | Type        |          | 1x    | Internal     |
+---------------------+------------+-------------+----------+-------+--------------+

ヒント:B.[key]オブジェクト識別子として結果に追加できます。

要するにアイデア

  • OPENJSONJSON を取得するためにfirst を使用します。-clauseWITHを使用すると、JSON-props を列としてアドレス指定できます。managedObejctsをJSON 自体として返します。
  • もう 1 つを使用OPENJSONして、管理対象オブジェクトに飛び込みます。
  • これにより、オブジェクトの配列が返されます。valueを別の に渡すことができOPENJSONます。
  • valueを単独で JSON として解釈できる場合はいつでも、もう 1 つ を使用します。OPENJSON今回はWITH-clause を使用して、内部の props を列として取得します。

この結果をテーブル (宣言、一時、物理など) に挿入して、この読みやすいセットを続行できます。

于 2020-10-21T16:32:50.217 に答える