現在、SQL Serverの「OPENJSON WITH(...」構文を使用してJSONファイルのほとんどを解析できます。ただし、この特定のファイルには、処理方法がわからないネストされた配列が含まれています。
私が読んだ例の多くは、変数としてJSONを参照しています。この場合、ファイルを呼び出しています:
select DEV_JSON.*
from OPENROWSET
(BULK 'C:\Users\Myuser\Documents\JSON_extract.json', SINGLE_CLOB) as my_datafile
CROSS APPLY OPENJSON(BulkColumn)
WITH
(DOC_ID varchar(100) '$.doc._id',
DOC_REV varchar(45) '$.doc._rev',
DELY_APPL_NAME varchar(20) '$.doc.delivery.application',
DELY_SENT_BY varchar(25) '$.doc.delivery.sender.id',
DELY_SENT_TYPO varchar(20) '$.doc.delivery.sender.type',
.....
....
...
..) as DEV_JSON
属性の1つにネストされた配列が含まれています。以下に、JSONの最初の5つの属性と、ネストされた「受信者」配列をコピーしました。
このセクションを解析するためにSQLをどのように構成しますか?
"doc": {
"_id": "[email protected]",
"_rev": "3-e119db13dae8d50ae0c4579ba9c87fc9",
"delivery": {
"application": "App_XYZ",
"sender": {
"id": "[email protected]",
"type": "user"
},
"recipients": [{
"type": "email",
"recipient": "\"Artzer, Daniel J\" <[email protected]>",
"sentTS": "2017-10-18T13:04:00.133Z"
},
{
"type": "email",
"recipient": "\"Higgins, Laura L\" <[email protected]>",
"sentTS": "2017-10-18T13:04:00.133Z"
},
{
"type": "email",
"recipient": "\"Friedman, Brian\" <[email protected]>",
"sentTS": "2017-10-18T13:04:00.133Z"
},
{
"type": "email",
"recipient": "\"Garcia, Charlie M\" <[email protected]>",
"sentTS": "2017-10-18T13:04:00.133Z"
}
]
},
私は同じ問題を抱えていましたが、複数のCROSS APPLY句を使用して解決しました。
JSONの例を次に示します。
DECLARE @PermsJSON NVARCHAR(MAX) =
N'[{
"AppId": 1,
"Perms":
[{
"Permission": ["AA", "BB"],
"PermissionTypeID": 2
},
{
"Permission": ["10"],
"PermissionTypeID": 1
}]
},
{
"AppId": 2,
"Perms":
[{
"Permission": ["IM", "NM"],
"PermissionTypeID": 2
},
{
"Permission": ["42"],
"PermissionTypeID": 1
}]
}]';
そして、次のクエリを使用して解析できます。
SELECT
a.AppId
,[Permission] = c.Value
,b.PermissionTypeID
FROM
OPENJSON(@PermsJSON)
WITH
(
AppId INT N'$.AppId'
,Perms NVARCHAR(MAX) AS JSON
) AS a
CROSS APPLY
OPENJSON(a.Perms)
WITH
(
PermissionTypeID INT
,[Permission] NVARCHAR(MAX) AS JSON
) AS b
CROSS APPLY OPENJSON(b.Permission) AS c;
結果は次のようになります。
AppId Permission PermissionTypeID
1 AA 2
1 BB 2
1 10 1
2 IM 2
2 NM 2
2 42 1
[〜#〜] much [〜#〜]検索の後、私はついにこの問題の答えを発見しました。次のように、ネストされた配列をクエリの別のJSON列として含める必要があります。
WITH
(DOC_ID varchar(100) '$.doc._id',
DOC_REV varchar(45) '$.doc._rev',
DELY_APPL_NAME varchar(20) '$.doc.delivery.application',
DELY_SENT_BY varchar(25) '$.doc.delivery.sender.id',
DELY_SENT_TYPO varchar(20) '$.doc.delivery.sender.type',
RECIPS nvarchar(max) '$.doc.delivery.recipients' as JSON,
PAYLOAD_START_TIME varchar(30) '$.doc.payload.startTS',
....
...
..
) as my_query
そのため、JSONドキュメントごとに1つのレコードが作成され、(この場合)JSONテキストを含むvarchar列があります。
次に、この列に対して別のクエリを実行してJSONを解析し、親に関連付けられた「子テーブル」を作成できます。