解析 JSON 数据并插入 SQL 服务器中的多个表

Parse JSON data and insert into multiple tables in SQL Server

我有一个JSON,其中包含以下格式的客户信息

{
  "customerdata": [
    {
      "customerID": "abcsd112-1234-4c01-abcd-bb2fb084dc52",
      "customerDetails": [
        {
          "fieldId": "100",
          "fieldValue": "ABC"
        },
        {
          "fieldId": "101",
          "fieldValue": "TESTCUSTOMER001"
        },
        {
          "fieldId": "102",
          "fieldValue": "1000"
        },
        {
          "fieldId": "103",
          "fieldValue": "TESTNAME"
        }     
            
      ]
    },
    {
      "customerID": "cdfsd112-4c01-45d7-abcd-9c9662d4ca30",
      "customerDetails": [
        {
          "fieldId": "100",
          "fieldValue": "CDE"
        },
        {
          "fieldId": "101",
          "fieldValue": "TESTCUSTOMER002"
        },
        {
          "fieldId": "102",
          "fieldValue": "1002"
        },
        {
          "fieldId": "103",
          "fieldValue": "TESTNAME2"
        }    
      ]
    }    
  ]
}

根据这个 JSON 数据,我想将数据插入到两个单独的 table 中。以这样一种方式,客户 ID 详细信息到一个 table (CustomerDetails) 和客户字段详细信息(customerDetails json 节点)到另一个 table ( CustomerFieldData) 外键引用第一个 table(CustomerID).

下面是 table 所需的

  1. CustomerDetails table 结构,其中 JSON 的 customerID 应插入到 CustomerUniqueGUID 列,客户名称将来自 customerDetails json 节点的字段 ID 101
    CREATE TABLE [CustomerDetails](
    [CustomerID] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [CustomerUniqueGUID] UNIQUEIDENTIFIER NOT NULL,
    [CustomerName] [varchar](100) NULL, 
    [IsActive] [bit] NULL)
    
  2. 客户字段数据 Table
    CREATE TABLE [CustomerFieldData](
        [CustomerFieldDataID] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY,
        [CustomerID] [bigint] NOT NULL FOREIGN KEY REFERENCES [CustomerDetails] ([CustomerID]), 
        [FieldID] [varchar](100) NOT NULL,
        [FieldValue] [varchar](100) NOT NULL)
    

我创建了一个示例存储过程来执行相同的操作。

ALTER PROCEDURE [InsertCustomerInfo]
    @CustomerJson NVarchar(MAX) 
AS
BEGIN
      
        INSERT INTO CustomerDetails (CustomerUniqueGUID,CustomerName)
        SELECT Customer.customerID, Fields.fieldValue FROM 
        OPENJSON(@CustomerJson)
                        WITH ([customerdata] nvarchar(max) as json
                        ) AS CustomerBatch
                        cross apply openjson (CustomerBatch.[customerdata])
                        with
                        (
                            customerID varchar(100),
                            customerDetails nvarchar(max) as json
                        ) AS Customer
                        cross apply openjson (Customer.customerDetails) with
                        (   
                            fieldId nvarchar(100),
                            fieldValue nvarchar(max)
                        ) as Fields
                        WHERE Fields.fieldID='101'              
        AND CustomerDetails.CustomerUniqueGUID not in (SELECT CustomerUniqueGUID FROM CustomerDetails WHERE ISActive=1 )

                
        If @@ROWCOUNT > 0               
        BEGIN
            INSERT INTO [CustomerFieldData](CustomerID,FieldID,FieldValue) SELECT L.CustomerID,Fields.fieldId,Fields.fieldValue FROM    
            CustomerDetails L INNER JOIN  
            OPENJSON(@CustomerJson)
            WITH ([customerdata] nvarchar(max) as json
            ) AS CustomerBatch
            cross apply openjson (CustomerBatch.[customerdata])
            with
            (   customerID varchar(100),
                customerDetails nvarchar(max) as json
            ) AS Customer
            cross apply openjson (Customer.customerDetails) with
            (   
                fieldId nvarchar(100),
                fieldValue nvarchar(max)
            ) as Fields
            ON L.CustomerUniqueGUID=Customers.customerID
                                        

        END  
    
END

但 CustomerFieldData 的数据没有正常发生,需要更多时间。我的脚本有什么问题吗?请帮助。

您可以在此处使用 INSERTOUTPUT 来获取新 ID 和 GUID 的值:

DECLARE @JSON nvarchar(MAX) = N'{
  "customerdata": [
    {
      "customerID": "abcsd112-1234-4c01-abcd-bb2fb084dc52",
      "customerDetails": [
        {
          "fieldId": "100",
          "fieldValue": "ABC"
        },
        {
          "fieldId": "101",
          "fieldValue": "TESTCUSTOMER001"
        },
        {
          "fieldId": "102",
          "fieldValue": "1000"
        },
        {
          "fieldId": "103",
          "fieldValue": "TESTNAME"
        }     
            
      ]
    },
    {
      "customerID": "cdfsd112-4c01-45d7-abcd-9c9662d4ca30",
      "customerDetails": [
        {
          "fieldId": "100",
          "fieldValue": "CDE"
        },
        {
          "fieldId": "101",
          "fieldValue": "TESTCUSTOMER002"
        },
        {
          "fieldId": "102",
          "fieldValue": "1002"
        },
        {
          "fieldId": "103",
          "fieldValue": "TESTNAME2"
        }    
      ]
    }    
  ]
}';

CREATE TABLE #CustomerIDs (CustomerID bigint,
                           CustomerUniqueGUID varchar(100)) ;

INSERT INTO dbo.CustomerDetails (CustomerUniqueGUID,CustomerName)
OUTPUT inserted.CustomerID, inserted.CustomerUniqueGUID
INTO #CustomerIDs
SELECT OJ.customerID,
       CD.fieldValue
FROM OPENJSON(@JSON,'$.customerdata')
     WITH(customerID varchar(100), 
          customerDetails nvarchar(MAX) AS JSON) OJ
     CROSS APPLY OPENJSON(OJ.customerDetails)
                 WITH(fieldId int,
                      fieldValue varchar(100)) CD
WHERE CD.fieldID = 101;


INSERT INTO dbo.CustomerFieldData (CustomerID,FieldID,FieldValue)
SELECT CI.CustomerID,
       CD.fieldID,
       CD.fieldValue
FROM OPENJSON(@JSON,'$.customerdata')
     WITH (customerID varchar(100), --Let's use the right data type again
           customerDetails nvarchar(MAX) AS JSON) OJ
     CROSS APPLY OPENJSON(OJ.customerDetails)
                 WITH(fieldId int,
                      fieldValue varchar(100)) CD
     JOIN #CustomerIDs CI ON OJ.customerID = CI.CustomerUniqueGUID



DROP TABLE #CustomerIDs;
GO
SELECT *
FROM dbo.CustomerDetails;

SELECT *
FROM dbo.CustomerFieldData;