解析 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 所需的
- 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)
- 客户字段数据 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 的数据没有正常发生,需要更多时间。我的脚本有什么问题吗?请帮助。
您可以在此处使用 INSERT
和 OUTPUT
来获取新 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;
我有一个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 所需的
- 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)
- 客户字段数据 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 的数据没有正常发生,需要更多时间。我的脚本有什么问题吗?请帮助。
您可以在此处使用 INSERT
和 OUTPUT
来获取新 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;