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

如何用SQL Server内置JSON方法实现EAV数据动态生成JSON

动态将EAV结构Vehicle表转换为层级JSON(SQL Server)

需求说明

现有类EAV结构的dbo.Vehicle表,需生成指定层级结构的JSON,要求每个EAV属性作为JSON对象的独立键,且后续新增属性时无需手动修改代码即可自动适配。

示例数据结构

CREATE TABLE dbo.Vehicle (CustomerID int NOT NULL,
                          VehicleID int NOT NULL,
                          ColumnName varchar(30),
                          ColumnValue varchar(100));

INSERT INTO dbo.Vehicle (CustomerID,
                         VehicleID,
                         ColumnName,
                         ColumnValue)
VALUES(1,1,'Make','Ford'),
      (1,1,'Model','Focus'),
      (1,1,'Colour','Blue'),
      (1,2,'Make','Ford'),
      (1,2,'Model','Fiesta'),
      (1,2,'Colour','Black'),
      (2,1,'Make','Honda'),
      (2,1,'Model','Jazz'),
      (2,1,'Colour','Grey'),
      (2,1,'Transmission','Automatic');

目标JSON格式

[
    {
        "CustomerID": 1,
        "Vehicles": [
            {
                "VehicleID": 1,
                "Make": "Ford",
                "Model": "Focus",
                "Colour": "Blue"
            },
            {
                "VehicleID": 2,
                "Make": "Ford",
                "Model": "Fiesta",
                "Colour": "Black"
            }
        ]
    },
    {
        "CustomerID": 2,
        "Vehicles": [
            {
                "VehicleID": 1,
                "Make": "Honda",
                "Model": "Jazz",
                "Colour": "Grey",
                "Transmission": "Automatic"
            }
        ]
    }
]

现有方案的不足

  • 静态方案需手动枚举所有属性,新增属性时必须修改代码。
  • 字符串拼接方案(STRING_AGG)繁琐,维护性差,且需手动处理JSON转义,容易出错。

基于SQL Server内置JSON函数的动态方案

方案一:SQL Server 2022+(推荐)

利用SQL Server 2022新增的JSON_OBJECT_AGG和JSON_ARRAYAGG聚合函数,直接动态生成键值对和数组,无需手动维护属性列表:

SELECT
  JSON_ARRAYAGG(
    JSON_OBJECT(
      'CustomerID': CustomerID,
      'Vehicles': Vehicles
    ) ORDER BY CustomerID
  ) AS FinalJson
FROM (
  SELECT
    CustomerID,
    JSON_ARRAYAGG(
      JSON_OBJECT(
        'VehicleID': VehicleID,
        -- 动态聚合当前Vehicle的所有EAV属性为键值对
        (SELECT JSON_OBJECT_AGG(ColumnName, ColumnValue) 
         FROM dbo.Vehicle v2 
         WHERE v2.CustomerID = v1.CustomerID AND v2.VehicleID = v1.VehicleID)
      ) ORDER BY VehicleID
    ) AS Vehicles
  FROM dbo.Vehicle v1
  GROUP BY CustomerID
) cust;

方案优势

  • 完全动态:新增ColumnName时自动纳入JSON,无需修改代码。
  • 自动转义:JSON_OBJECT_AGG会自动处理JSON特殊字符的转义,避免手动调用STRING_ESCAPE。
  • 代码简洁:利用内置JSON函数替代字符串拼接,可读性和维护性大幅提升。

方案二:SQL Server 2016-2019(兼容低版本)

通过动态SQL自动生成静态转换逻辑,结合FOR JSON PATH实现动态适配:

DECLARE @cols NVARCHAR(MAX);

-- 动态获取所有唯一的ColumnName
SELECT @cols = STRING_AGG(
    'MAX(CASE WHEN V.ColumnName = ''' + ColumnName + ''' THEN V.ColumnValue END) AS ' + QUOTENAME(ColumnName),
    ','
)
FROM (SELECT DISTINCT ColumnName FROM dbo.Vehicle) t;

-- 构造并执行动态SQL
DECLARE @sql NVARCHAR(MAX) = N'
SELECT C.CustomerID,
       (SELECT V.VehicleID, ' + @cols + '
        FROM dbo.Vehicle V
        WHERE V.CustomerID = C.CustomerID
        GROUP BY V.VehicleID
        FOR JSON PATH) AS Vehicles
FROM dbo.Vehicle C
GROUP BY C.CustomerID
FOR JSON PATH;
';

EXEC sp_executesql @sql;

方案优势

  • 兼容SQL Server 2016及以上版本(FOR JSON PATH从2016开始支持)。
  • 自动适配新增属性,无需手动修改核心逻辑。
  • 利用FOR JSON PATH自动处理JSON格式和转义,比字符串拼接更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 07:02:52