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

SQL Server中如何向已有JSON列添加嵌套属性NewAttr

在SQL Server中更新JSON列并插入嵌套属性

问题背景

现有目标JSON列数据示例:

{ "Attr1": "AAAAAAAAA", "Attr2": 70, "Attr3": null, "Attr4": false }

需要在Attr2之后插入NewAttr嵌套属性,规则如下:

  • 当SourceTable1.Column1和SourceTable2.Column2均存在时:
    "NewAttr": { "SourceTable1.Column1": "12xx12", "SourceTable2.Column2": "0192xx" }
    
  • 仅SourceTable1.Column1存在时:
    "NewAttr": { "SourceTable1.Column1": "12xx12" }
    
  • 仅SourceTable2.Column2存在时:
    "NewAttr": { "SourceTable2.Column2": "0192xx" }
    
  • 两者均不存在时:
    "NewAttr": {}
    

之前尝试的SELECT语句无法生成符合要求的嵌套结构:

SELECT top 10000 JSON_MODIFY(dt.DestinationColumn, '$.NewAttr', st.Column1) 
FROM dbo.Joiningtable jt 
INNER JOIN dbo.DestinationTable dt ON dt.ID = jt.TID 
INNER JOIN dbo.SourceTable st ON jt.TID = st.ID

最终需求是更新DestinationTable.DestinationColumn中的JSON数据。

解决方案

1. 动态构建NewAttr的JSON内容

通过LEFT JOIN关联所有相关表,根据字段存在情况用STRING_AGG拼接键值对,生成NewAttr的JSON字符串:

SELECT 
    dt.ID,
    CONCAT(
        '{',
        STRING_AGG(
            CASE
                WHEN st1.Column1 IS NOT NULL THEN '"SourceTable1.Column1": "12xx12"'
                WHEN st2.Column2 IS NOT NULL THEN '"SourceTable2.Column2": "0192xx"'
            END,
            ','
        ),
        '}'
    ) AS NewAttrJson
FROM dbo.DestinationTable dt
LEFT JOIN dbo.Joiningtable jt ON dt.ID = jt.TID
LEFT JOIN dbo.SourceTable1 st1 ON jt.TID = st1.ID
LEFT JOIN dbo.SourceTable2 st2 ON jt.TID = st2.ID
GROUP BY dt.ID

LEFT JOIN确保即使源表无匹配数据也能处理,STRING_AGG会自动忽略空值,最终生成符合规则的JSON对象。

2. 更新目标JSON列

方式一:不严格要求属性顺序

直接用JSON_MODIFY将构建好的NewAttr插入到目标JSON列中,注意用JSON_QUERY避免转义:

UPDATE dt
SET dt.DestinationColumn = JSON_MODIFY(
    dt.DestinationColumn,
    '$.NewAttr',
    JSON_QUERY(na.NewAttrJson)
)
FROM dbo.DestinationTable dt
JOIN (
    SELECT 
        dt.ID,
        CONCAT(
            '{',
            STRING_AGG(
                CASE
                    WHEN st1.Column1 IS NOT NULL THEN '"SourceTable1.Column1": "12xx12"'
                    WHEN st2.Column2 IS NOT NULL THEN '"SourceTable2.Column2": "0192xx"'
                END,
                ','
            ),
            '}'
        ) AS NewAttrJson
    FROM dbo.DestinationTable dt
    LEFT JOIN dbo.Joiningtable jt ON dt.ID = jt.TID
    LEFT JOIN dbo.SourceTable1 st1 ON jt.TID = st1.ID
    LEFT JOIN dbo.SourceTable2 st2 ON jt.TID = st2.ID
    GROUP BY dt.ID
) na ON dt.ID = na.ID

方式二:严格要求NewAttr在Attr2之后

如果需要确保NewAttr位于Attr2之后,需要重新重组JSON结构:

UPDATE dt
SET dt.DestinationColumn = 
    JSON_MODIFY(
        dt.DestinationColumn,
        '$.',
        (
            SELECT 
                Attr1,
                Attr2,
                JSON_QUERY(na.NewAttrJson) AS NewAttr,
                Attr3,
                Attr4
            FROM OPENJSON(dt.DestinationColumn)
            WITH (
                Attr1 NVARCHAR(100),
                Attr2 INT,
                Attr3 NVARCHAR(100),
                Attr4 BIT
            )
            FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
        )
    )
FROM dbo.DestinationTable dt
JOIN (
    SELECT 
        dt.ID,
        CONCAT(
            '{',
            STRING_AGG(
                CASE
                    WHEN st1.Column1 IS NOT NULL THEN '"SourceTable1.Column1": "12xx12"'
                    WHEN st2.Column2 IS NOT NULL THEN '"SourceTable2.Column2": "0192xx"'
                END,
                ','
            ),
            '}'
        ) AS NewAttrJson
    FROM dbo.DestinationTable dt
    LEFT JOIN dbo.Joiningtable jt ON dt.ID = jt.TID
    LEFT JOIN dbo.SourceTable1 st1 ON jt.TID = st1.ID
    LEFT JOIN dbo.SourceTable2 st2 ON jt.TID = st2.ID
    GROUP BY dt.ID
) na ON dt.ID = na.ID

通过OPENJSON解析原JSON,按指定顺序重新生成JSON字符串,确保NewAttr在Attr2之后。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 10:05:20