我在Sql server中有以下Json对象。我想将这些数据与它们的关系(即外键)插入多个表中:
DECLARE @JsonObject NVARCHAR(MAX) = N'{
"FirstElement":{
"Name":"ABC",
"Location":"East US",
"Region":"West US",
"InnerElement":[
{
"Name":"IE1",
"Description":"IE1 Description",
"Type":"Small",
"InnerMostElement":[
{
"Key":"Name",
"Value":"IME1"
},
{
"Key":"AnotherProperty",
"Value":"Value1"
}
]
},
{
"Name":"IE2",
"Description":"IE2 Description",
"Type":"Medium",
"InnerMostElement":[
{
"Key":"Name",
"Value":"IME2"
},
{
"Key":"Address",
"Value":"Xyz"
},
{
"Key":"Type",
"Value":"Simple"
},
{
"Key":"LastProperty",
"Value":"ValueX"
}
]
}
]
}
}'
表格结构如下:
我想在 Table2 和 InnerMostElement中的 Table1 , InnerElement 数据中插入 FirstElement 数据 表3 中的数据。
答案 0 :(得分:2)
简单的部分是第一个表,因为我们只插入一行并且它没有依赖关系:
BEGIN TRANSACTION;
INSERT Table1([Name], [Location], [Region])
SELECT [Name], [Location], [Region]
FROM OPENJSON(@JsonObject, '$.FirstElement')
WITH (
[Name] VARCHAR(100),
[Location] VARCHAR(100),
[Region] VARCHAR(100)
);
DECLARE @Table1Id INT = SCOPE_IDENTITY();
困难的部分是下一张桌子。我们需要捕获插入行的所有标识,以及还要插入到表3中的所有数据。因为OUTPUT
的{{1}}子句仅限于在基表中输出值,我们需要使用INSERT
技巧:
MERGE
如果要使用JSON主要填充表,使用DECLARE @Table3Input TABLE([Table2Id] INT, [InnerMostElement] NVARCHAR(MAX));
MERGE Table2
USING (
SELECT [Name], [Description], [Type], [InnerMostElement]
FROM OPENJSON(@JsonObject, '$.FirstElement.InnerElement')
WITH (
[Name] VARCHAR(100),
[Description] VARCHAR(100),
[Type] VARCHAR(100),
[InnerMostElement] NVARCHAR(MAX) AS JSON
)
) AS J
ON 1 = 0 -- Always INSERT
WHEN NOT MATCHED THEN
INSERT([Table1Id], [Name], [Description], [Type])
VALUES (@Table1Id, J.[Name], J.[Description], J.[Type])
OUTPUT inserted.Id, J.[InnerMostElement]
INTO @Table3Input([Table2Id], [InnerMostElement]);
个对象生成连续值(使用SEQUENCE
)可能更方便,而无需将整个JSON捕获到临时值表。这将大大简化这一点,并消除对sp_sequence_get_range
。
最后一张表再次简单:
MERGE
事务在逻辑上是必要的,以确保完全插入此对象,或者根本不插入。
最终输出:
INSERT Table3([Table2Id], [Key], [Value])
SELECT [Table2Id], KV.[Key], KV.[Value]
FROM @Table3Input CROSS APPLY (
SELECT [Key], [Value]
FROM OPENJSON([InnerMostElement])
WITH (
[Key] VARCHAR(100),
[Value] VARCHAR(100)
)
) AS KV;
COMMIT;
+----+------+----------+---------+
| Id | Name | Location | Region |
+----+------+----------+---------+
| 1 | ABC | East US | West US |
+----+------+----------+---------+
+----+----------+------+-----------------+--------+
| Id | Table1Id | Name | Description | Type |
+----+----------+------+-----------------+--------+
| 1 | 1 | IE1 | IE1 Description | Small |
| 2 | 1 | IE2 | IE2 Description | Medium |
+----+----------+------+-----------------+--------+
为了完整性,请按以下步骤将其转换回JSON:
+----+----------+-----------------+--------+
| Id | Table2Id | Key | Value |
+----+----------+-----------------+--------+
| 1 | 1 | Name | IME1 |
| 2 | 1 | AnotherProperty | Value1 |
| 3 | 2 | Name | IME2 |
| 4 | 2 | Address | Xyz |
| 5 | 2 | Type | Simple |
| 6 | 2 | LastProperty | ValueX |
+----+----------+-----------------+--------+