You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将嵌套JSON中的数据保存到SQL Server的关联表中

没问题!既然你已经成功把嵌套JSON解析成了关系型数据格式,接下来要把这些数据插入到关联的Project、SubSection、Items表中,核心要注意外键依赖的插入顺序和空节点的过滤处理,我给你整理了一套完整的分步方案:

解决方案:分步插入关联表数据

因为三个表存在外键依赖(SubSection依赖Project的IdProject,Items依赖SubSection的IdStructure),所以必须按「Project → SubSection → Items」的顺序插入,同时要处理JSON里存在的空节点(比如第三个项目的空SubSection、第四个项目的缺失Items)。

1. 先插入Project表

从解析后的JSON中提取唯一的项目数据,避免重复插入:

INSERT INTO Project (IdProject, Name)
SELECT DISTINCT 
    Projects.IdProject, 
    Projects.Name
FROM openjson (@json)
with (
    IdProject int,
    Name nvarchar(100),
    SubSection nvarchar(max) as json
) as Projects
-- 可选:如果表中已有相同IdProject,跳过重复数据
WHERE NOT EXISTS (SELECT 1 FROM Project WHERE IdProject = Projects.IdProject);

2. 再插入SubSection表

关联已插入的Project表,同时过滤掉JSON中空的SubSection节点:

INSERT INTO SubSection (IdStructure, IdProject, Name)
SELECT DISTINCT
    Structures.IdStructure,
    Projects.IdProject,
    Structures.Name
FROM openjson (@json)
with (
    IdProject int,
    SubSection nvarchar(max) as json
) as Projects
OUTER APPLY openjson (Projects.SubSection)
with (
    IdStructure int,
    Name nvarchar(100)
) as Structures
-- 过滤掉空的SubSection节点(IdStructure为NULL的情况)
WHERE Structures.IdStructure IS NOT NULL
-- 可选:跳过已存在的SubSection数据
AND NOT EXISTS (SELECT 1 FROM SubSection WHERE IdStructure = Structures.IdStructure);

3. 最后插入Items表

关联已插入的SubSection表,处理Items节点缺失的情况:

INSERT INTO Items (IdProperty, IdStructure, Name, DataType, [Precision], [Scale], IsNullable, ObjectName, DefaultType, DefaultValue)
SELECT DISTINCT
    Properties.IdProperty,
    Structures.IdStructure,
    Properties.NamePreoperty,
    Properties.DataType,
    Properties.[Precision],
    Properties.[Scale],
    Properties.IsNullable,
    Properties.ObjectName,
    Properties.DefaultType,
    Properties.DefaultValue
FROM openjson (@json)
with (
    IdProject int,
    SubSection nvarchar(max) as json
) as Projects
OUTER APPLY openjson (Projects.SubSection)
with (
    IdStructure int,
    Items nvarchar(max) as json
) as Structures
-- 当Items节点不存在时,转为空数组避免OPENJSON报错
OUTER APPLY openjson (ISNULL(Structures.Items, '[]'))
with (
    IdProperty int,
    NamePreoperty nvarchar(100) '$.Name',
    DataType int,
    [Precision] int,
    [Scale] int,
    IsNullable bit,
    ObjectName nvarchar(100),
    DefaultType int,
    DefaultValue nvarchar(100)
) as Properties
-- 过滤掉空的Items节点(IdProperty为NULL的情况)
WHERE Properties.IdProperty IS NOT NULL
-- 可选:跳过已存在的Items数据
AND NOT EXISTS (SELECT 1 FROM Items WHERE IdProperty = Properties.IdProperty);

额外优化建议

  • 事务包裹:如果要确保三个表的插入操作原子性(要么全成功,要么全失败),可以把所有插入语句放在事务里:
BEGIN TRANSACTION;
BEGIN TRY
    -- 插入Project的语句
    -- 插入SubSection的语句
    -- 插入Items的语句
    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION;
    THROW; -- 抛出错误信息,方便排查问题
END CATCH;
  • 重复数据处理:上面的WHERE NOT EXISTS子句是为了避免插入重复的主键数据,如果你的表主键是自增类型,或者业务允许重复(不推荐),可以去掉这些判断。
  • 空值兼容:ISNULL(Structures.Items, '[]')的作用是当JSON里没有Items节点时,给OPENJSON一个空数组,避免出现解析错误。

内容的提问来源于stack exchange,提问作者Sunny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 05:42:30